diff --git a/src/Makevars.in b/src/Makevars.in index cf9de300..5a9ae580 100644 --- a/src/Makevars.in +++ b/src/Makevars.in @@ -1,4 +1,5 @@ -PKG_CPPFLAGS=-I. -Icommon -Ikms \ +PKG_CPPFLAGS=-I. -Icommon -Ikms -Iutf8proc \ + -D_XOPEN_SOURCE=700 -D_DEFAULT_SOURCE \ -DKMS_MESSAGE_ENABLE_CRYPTO -DKMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO \ -DBSON_COMPILATION -DMONGOC_COMPILATION -DOPENSSL_SUPPRESS_DEPRECATED @cflags@ @@ -29,8 +30,8 @@ LIBMONGOC=mongoc/mongoc-array.o common/common-b64.o mongoc/mongoc-buffer.o \ mongoc/mongoc-stream-tls-openssl.o mongoc/mongoc-stream-tls-openssl-bio.o \ mongoc/mongoc-cluster-sasl.o mongoc/mongoc-cmd.o \ mongoc/mongoc-change-stream.o mongoc/mongoc-client-session.o mongoc/mongoc-cluster-cyrus.o \ - mongoc/mongoc-compression.o mongoc/mongoc-cyrus.o mongoc/mongoc-write-command-legacy.o \ - mongoc/mongoc-linux-distro-scanner.o mongoc/mongoc-stream-file.o \ + mongoc/mongoc-compression.o mongoc/mongoc-cyrus.o \ + mongoc/mongoc-linux-distro-scanner.o mongoc/mongoc-stream-file.o mongoc/mcd-rpc.o mongoc/mongoc-deprioritized-servers.o \ mongoc/mongoc-opts.o mongoc/mongoc-opts-helpers.o \ mongoc/mongoc-cursor-cmd.o mongoc/mongoc-cursor-cmd-deprecated.o \ mongoc/mongoc-cursor-find.o mongoc/mongoc-cursor-find-cmd.o mongoc/mongoc-cursor-find-opquery.o \ @@ -39,7 +40,7 @@ LIBMONGOC=mongoc/mongoc-array.o common/common-b64.o mongoc/mongoc-buffer.o \ mongoc/mongoc-cluster-aws.o mongoc/mongoc-generation-map.o mongoc/mongoc-timeout.o \ mongoc/mongoc-server-monitor.o mongoc/mongoc-topology-background-monitoring.o common/common-thread.o \ mongoc/mongoc-optional.o mongoc/mongoc-server-api.o mongoc/mongoc-http.o mongoc/mongoc-ocsp-cache.o \ - mongoc/mongoc-shared.o mongoc/mongoc-ts-pool.o + mongoc/mongoc-shared.o mongoc/mongoc-ts-pool.o utf8proc/utf8proc.o LIBKMS=kms/hexlify.o kms/kms_crypto_windows.o kms/kms_kv_list.o kms/kms_request.o \ kms/kms_response.o kms/kms_b64.o kms/kms_crypto_libcrypto.o kms/kms_decrypt_request.o kms/kms_message.o \ diff --git a/src/Makevars.win b/src/Makevars.win index 71165bf3..3f83c069 100644 --- a/src/Makevars.win +++ b/src/Makevars.win @@ -1,9 +1,10 @@ PKG_CPPFLAGS = \ - -I. -Icommon -Ikms \ + -I. -Icommon -Ikms -Iutf8proc \ -DBSON_COMPILATION -DMONGOC_COMPILATION \ -DMONGOC_ENABLE_SSL_SECURE_CHANNEL -DMONGOC_ENABLE_CRYPTO_CNG \ -DKMS_MESSAGE_ENABLE_CRYPTO -DKMS_MESSAGE_ENABLE_CRYPTO_CNG \ - -DMONGOC_HAVE_SASL_CLIENT_DONE -D__USE_MINGW_ANSI_STDIO + -DMONGOC_HAVE_SASL_CLIENT_DONE -D__USE_MINGW_ANSI_STDIO \ + -DKMS_MESSAGE_LITTLE_ENDIAN -DUTF8PROC_STATIC PKG_LIBS = \ -L. -Lmongoc -lstatmongoc \ @@ -35,9 +36,9 @@ LIBMONGOC=mongoc/mongoc-array.o common/common-b64.o mongoc/mongoc-buffer.o \ mongoc/mongoc-read-concern.o mongoc/mongoc-secure-channel.o mongoc/mongoc-apm.o \ mongoc/mongoc-crypto.o mongoc/mongoc-crypto-common-crypto.o mongoc/mongoc-crypto-cng.o mongoc/mongoc-handshake.o \ mongoc/mongoc-stream-tls-secure-channel.o \ - mongoc/mongoc-cluster-sasl.o mongoc/mongoc-cmd.o mongoc/mongoc-stream-file.o \ + mongoc/mongoc-cluster-sasl.o mongoc/mongoc-cmd.o mongoc/mongoc-stream-file.o mongoc/mcd-rpc.o mongoc/mongoc-deprioritized-servers.o \ mongoc/mongoc-change-stream.o mongoc/mongoc-client-session.o \ - mongoc/mongoc-compression.o mongoc/mongoc-write-command-legacy.o \ + mongoc/mongoc-compression.o \ mongoc/mongoc-sspi.o mongoc/mongoc-cluster-sspi.o mongoc/mongoc-queue.o \ mongoc/mongoc-opts.o mongoc/mongoc-opts-helpers.o \ mongoc/mongoc-cursor-cmd.o mongoc/mongoc-cursor-cmd-deprecated.o \ @@ -47,12 +48,13 @@ LIBMONGOC=mongoc/mongoc-array.o common/common-b64.o mongoc/mongoc-buffer.o \ mongoc/mongoc-cluster-aws.o mongoc/mongoc-generation-map.o mongoc/mongoc-timeout.o \ mongoc/mongoc-server-monitor.o mongoc/mongoc-topology-background-monitoring.o common/common-thread.o \ mongoc/mongoc-optional.o mongoc/mongoc-server-api.o mongoc/mongoc-http.o mongoc/mongoc-ocsp-cache.o \ - mongoc/mongoc-shared.o mongoc/mongoc-ts-pool.o + mongoc/mongoc-shared.o mongoc/mongoc-ts-pool.o utf8proc/utf8proc.o LIBKMS=kms/hexlify.o kms/kms_crypto_windows.o kms/kms_kv_list.o kms/kms_request.o \ kms/kms_response.o kms/kms_b64.o kms/kms_crypto_libcrypto.o kms/kms_decrypt_request.o kms/kms_message.o \ kms/kms_request_opt.o kms/kms_response_parser.o kms/kms_caller_identity_request.o \ - kms/kms_encrypt_request.o kms/kms_port.o kms/kms_request_str.o kms/sort.o + kms/kms_encrypt_request.o kms/kms_port.o kms/kms_request_str.o kms/sort.o \ + kms/kms_kmip_response_parser.o STATLIB = mongoc/libstatmongoc.a diff --git a/src/bson/bcon.c b/src/bson/bcon.c index fbb5b1e0..53ae80fe 100644 --- a/src/bson/bcon.c +++ b/src/bson/bcon.c @@ -22,7 +22,7 @@ #include #include "bcon.h" -#include "bson-config.h" +#include /* These stack manipulation macros are used to manage append recursion in * bcon_append_ctx_va(). They take care of some awkward dereference rules (the diff --git a/src/bson/bcon.h b/src/bson/bcon.h index 0562af2f..80b5a489 100644 --- a/src/bson/bcon.h +++ b/src/bson/bcon.h @@ -3,7 +3,7 @@ * @brief BCON (BSON C Object Notation) Declarations */ -#include "bson-prelude.h" +#include /* Copyright 2009-2013 MongoDB, Inc. * diff --git a/src/bson/bson-atomic.c b/src/bson/bson-atomic.c index a3ad5736..bb8eefcf 100644 --- a/src/bson/bson-atomic.c +++ b/src/bson/bson-atomic.c @@ -15,7 +15,7 @@ */ -#include "bson-atomic.h" +#include #ifdef BSON_OS_UNIX /* For sched_yield() */ @@ -25,7 +25,9 @@ int32_t bson_atomic_int_add (volatile int32_t *p, int32_t n) { - return n + bson_atomic_int32_fetch_add (p, n, bson_memory_order_seq_cst); + return n + bson_atomic_int32_fetch_add ((DECL_ATOMIC_INTEGRAL_INT32 *) p, + n, + bson_memory_order_seq_cst); } int64_t diff --git a/src/bson/bson-atomic.h b/src/bson/bson-atomic.h index 845fe342..a28c0be6 100644 --- a/src/bson/bson-atomic.h +++ b/src/bson/bson-atomic.h @@ -14,16 +14,16 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_ATOMIC_H #define BSON_ATOMIC_H -#include "bson-config.h" -#include "bson-compat.h" -#include "bson-macros.h" +#include +#include +#include #ifdef _MSC_VER #include @@ -47,7 +47,8 @@ enum bson_memory_order { #define MSVC_MEMORDER_SUFFIX(X) #endif -#if defined(USE_LEGACY_GCC_ATOMICS) || (!defined(__clang__) && __GNUC__ == 4) +#if defined(USE_LEGACY_GCC_ATOMICS) || \ + (!defined(__clang__) && __GNUC__ == 4) || defined(__xlC__) #define BSON_USE_LEGACY_GCC_ATOMICS #else #undef BSON_USE_LEGACY_GCC_ATOMICS @@ -61,6 +62,7 @@ enum bson_memory_order { #ifdef BSON_USE_LEGACY_GCC_ATOMICS #undef BSON_IF_GNU_LIKE #define BSON_IF_GNU_LIKE(...) +#define BSON_IF_MSVC(...) #define BSON_IF_GNU_LEGACY_ATOMICS(...) __VA_ARGS__ #else #define BSON_IF_GNU_LEGACY_ATOMICS(...) @@ -379,6 +381,10 @@ DECL_ATOMIC_INTEGRAL (int, int, ) #endif #endif +#ifndef DECL_ATOMIC_INTEGRAL_INT32 +#define DECL_ATOMIC_INTEGRAL_INT32 int32_t +#endif + BSON_EXPORT (int64_t) _bson_emul_atomic_int64_fetch_add (int64_t volatile *val, int64_t v, diff --git a/src/bson/bson-clock.c b/src/bson/bson-clock.c index 95287dca..a9510c2e 100644 --- a/src/bson/bson-clock.c +++ b/src/bson/bson-clock.c @@ -14,17 +14,8 @@ * limitations under the License. */ - -#ifdef __APPLE__ -#include -#include -#include -#include -#endif - - -#include "bson-config.h" -#include "bson-compat.h" +#include +#include #if defined(BSON_HAVE_CLOCK_GETTIME) @@ -32,8 +23,7 @@ #include #endif -#include "bson-clock.h" - +#include /* *-------------------------------------------------------------------------- @@ -125,19 +115,6 @@ bson_get_monotonic_time (void) * int64_t to avoid truncation. */ clock_gettime (CLOCK_MONOTONIC, &ts); return (((int64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000)); -#elif defined(__APPLE__) - static mach_timebase_info_data_t info = {0}; - static double ratio = 0.0; - - if (!info.denom) { - /* the value from mach_absolute_time () * info.numer / info.denom - * is in nano seconds. So we have to divid by 1000.0 to get micro - * seconds*/ - mach_timebase_info (&info); - ratio = (double) info.numer / (double) info.denom / 1000.0; - } - - return mach_absolute_time () * ratio; #elif defined(_WIN32) /* Despite it's name, this is in milliseconds! */ int64_t ticks = GetTickCount64 (); diff --git a/src/bson/bson-clock.h b/src/bson/bson-clock.h index d2f14d49..a4845b74 100644 --- a/src/bson/bson-clock.h +++ b/src/bson/bson-clock.h @@ -14,16 +14,16 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_CLOCK_H #define BSON_CLOCK_H -#include "bson-compat.h" -#include "bson-macros.h" -#include "bson-types.h" +#include +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-cmp.h b/src/bson/bson-cmp.h index 98da8483..8db9ed95 100644 --- a/src/bson/bson-cmp.h +++ b/src/bson/bson-cmp.h @@ -14,15 +14,15 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_CMP_H #define BSON_CMP_H -#include "bson-compat.h" /* ssize_t */ -#include "bson-macros.h" /* BSON_CONCAT */ +#include /* ssize_t */ +#include /* BSON_CONCAT */ #include #include diff --git a/src/bson/bson-compat.h b/src/bson/bson-compat.h index ef492925..5f8e092f 100644 --- a/src/bson/bson-compat.h +++ b/src/bson/bson-compat.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_COMPAT_H @@ -31,8 +31,8 @@ #endif #endif -#include "bson-config.h" -#include "bson-macros.h" +#include +#include #ifdef BSON_OS_WIN32 @@ -64,7 +64,7 @@ #endif -#include "bson-macros.h" +#include #include @@ -145,134 +145,6 @@ typedef SSIZE_T ssize_t; * all its bits to 1. */ #define BSON_NUMERIC_LIMITS_MAX_UNSIGNED(T) ((T) (~((T) 0))) -/* Define numeric limit constants if not already available for C90 - * compatibility. These can be removed once C99 is declared the minimum - * supported C standard. */ -#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L - -#ifndef SCHAR_MAX -#define SCHAR_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (signed char) -#endif - -#ifndef SHRT_MAX -#define SHRT_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (short) -#endif - -#ifndef INT_MAX -#define INT_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (int) -#endif - -#ifndef LONG_MAX -#define LONG_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (long) -#endif - -#ifndef LLONG_MAX -#define LLONG_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (long long) -#endif - -#ifndef UCHAR_MAX -#define UCHAR_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (unsigned char) -#endif - -#ifndef USHRT_MAX -#define USHRT_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (unsigned short) -#endif - -#ifndef UINT_MAX -#define UINT_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (unsigned int) -#endif - -#ifndef ULONG_MAX -#define ULONG_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (unsigned long) -#endif - -#ifndef ULLONG_MAX -#define ULLONG_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (unsigned long long) -#endif - -#ifndef INT8_MAX -#define INT8_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (int8_t) -#endif - -#ifndef INT16_MAX -#define INT16_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (int16_t) -#endif - -#ifndef INT32_MAX -#define INT32_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (int32_t) -#endif - -#ifndef INT64_MAX -#define INT64_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (int64_t) -#endif - -#ifndef UINT8_MAX -#define UINT8_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (uint8_t) -#endif - -#ifndef UINT16_MAX -#define UINT16_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (uint16_t) -#endif - -#ifndef UINT32_MAX -#define UINT32_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (uint32_t) -#endif - -#ifndef UINT64_MAX -#define UINT64_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (uint64_t) -#endif - -#ifndef SIZE_MAX -#define SIZE_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (size_t) -#endif - -#ifndef PTRDIFF_MAX -#define PTRDIFF_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (ptrdiff_t) -#endif - -#ifndef SCHAR_MIN -#define SCHAR_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (signed char, SCHAR_MAX) -#endif - -#ifndef SHRT_MIN -#define SHRT_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (short, SHRT_MAX) -#endif - -#ifndef INT_MIN -#define INT_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (int, INT_MAX) -#endif - -#ifndef LONG_MIN -#define LONG_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (long, LONG_MAX) -#endif - -#ifndef LLONG_MIN -#define LLONG_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (long long, LLONG_MAX) -#endif - -#ifndef INT8_MIN -#define INT8_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (int8_t, INT8_MAX) -#endif - -#ifndef INT16_MIN -#define INT16_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (int16_t, INT16_MAX) -#endif - -#ifndef INT32_MIN -#define INT32_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (int32_t, INT32_MAX) -#endif - -#ifndef INT64_MIN -#define INT64_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (int64_t, INT64_MAX) -#endif - -#ifndef PTRDIFF_MIN -#define PTRDIFF_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (ptrdiff_t, PTRDIFF_MAX) -#endif - -#endif /* !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L */ - - #ifndef SSIZE_MAX #define SSIZE_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (ssize_t) #endif @@ -303,9 +175,9 @@ typedef signed char bool; #define bson_sync_synchronize() __sync_synchronize () #elif defined(__i386__) || defined(__i486__) || defined(__i586__) || \ defined(__i686__) || defined(__x86_64__) -#define bson_sync_synchronize() asm volatile("mfence" ::: "memory") +#define bson_sync_synchronize() asm volatile ("mfence" ::: "memory") #else -#define bson_sync_synchronize() asm volatile("sync" ::: "memory") +#define bson_sync_synchronize() asm volatile ("sync" ::: "memory") #endif #elif defined(_MSC_VER) #define bson_sync_synchronize() MemoryBarrier () diff --git a/src/bson/bson-context-private.h b/src/bson/bson-context-private.h index c88c87cc..04349735 100644 --- a/src/bson/bson-context-private.h +++ b/src/bson/bson-context-private.h @@ -14,14 +14,14 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_CONTEXT_PRIVATE_H #define BSON_CONTEXT_PRIVATE_H -#include "bson-context.h" +#include #include "common-thread-private.h" diff --git a/src/bson/bson-context.c b/src/bson/bson-context.c index 862a80a9..d1adfc47 100644 --- a/src/bson/bson-context.c +++ b/src/bson/bson-context.c @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-compat.h" +#include #include #include @@ -22,11 +22,11 @@ #include #include -#include "bson-atomic.h" -#include "bson-clock.h" -#include "bson-context.h" -#include "bson-context-private.h" -#include "bson-memory.h" +#include +#include +#include +#include +#include #include "common-thread-private.h" @@ -62,7 +62,9 @@ _bson_context_set_oid_seq32 (bson_context_t *context, /* IN */ bson_oid_t *oid) /* OUT */ { uint32_t seq = (uint32_t) bson_atomic_int32_fetch_add ( - (int32_t *) &context->seq32, 1, bson_memory_order_seq_cst); + (DECL_ATOMIC_INTEGRAL_INT32 *) &context->seq32, + 1, + bson_memory_order_seq_cst); seq = BSON_UINT32_TO_BE (seq); memcpy (&oid->bytes[BSON_OID_SEQ32_OFFSET], ((uint8_t *) &seq) + 1, diff --git a/src/bson/bson-context.h b/src/bson/bson-context.h index 3098ce60..8399b577 100644 --- a/src/bson/bson-context.h +++ b/src/bson/bson-context.h @@ -14,15 +14,15 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_CONTEXT_H #define BSON_CONTEXT_H -#include "bson-macros.h" -#include "bson-types.h" +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-decimal128.c b/src/bson/bson-decimal128.c index 9f4e9639..827d1165 100644 --- a/src/bson/bson-decimal128.c +++ b/src/bson/bson-decimal128.c @@ -19,10 +19,11 @@ #include #include -#include "bson-decimal128.h" -#include "bson-types.h" -#include "bson-macros.h" -#include "bson-string.h" +#include +#include +#include +#include +#include #define BSON_DECIMAL128_EXPONENT_MAX 6111 @@ -155,8 +156,6 @@ bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */ uint8_t significand_msb; /* the most signifcant significand bits (50-46) */ _bson_uint128_t significand128; /* temporary storage for significand decoding */ - size_t i; /* indexing variables */ - int j, k; memset (significand_str, 0, sizeof (significand_str)); @@ -212,7 +211,7 @@ bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */ */ is_zero = true; } else { - for (k = 3; k >= 0; k--) { + for (int k = 3; k >= 0; k--) { uint32_t least_digits = 0; _bson_uint128_divide1B ( significand128, &significand128, &least_digits); @@ -223,7 +222,7 @@ bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */ continue; } - for (j = 8; j >= 0; j--) { + for (int j = 8; j >= 0; j--) { significand[k * 9 + j] = least_digits % 10; least_digits /= 10; } @@ -264,7 +263,8 @@ bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */ *(str_out++) = '.'; } - for (i = 0; i < significand_digits && (str_out - str) < 36; i++) { + for (uint32_t i = 0; i < significand_digits && (str_out - str) < 36; + i++) { *(str_out++) = *(significand_read++) + '0'; } /* Exponent */ @@ -273,7 +273,8 @@ bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */ } else { /* Regular format with no decimal place */ if (exponent >= 0) { - for (i = 0; i < significand_digits && (str_out - str) < 36; i++) { + for (uint32_t i = 0; i < significand_digits && (str_out - str) < 36; + i++) { *(str_out++) = *(significand_read++) + '0'; } *str_out = '\0'; @@ -281,7 +282,7 @@ bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */ int32_t radix_position = significand_digits + exponent; if (radix_position > 0) { /* non-zero digits before radix */ - for (i = 0; + for (int32_t i = 0; i < radix_position && (str_out - str) < BSON_DECIMAL128_STRING; i++) { *(str_out++) = *(significand_read++) + '0'; @@ -295,8 +296,9 @@ bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */ *(str_out++) = '0'; } - for (i = 0; - (i < significand_digits - BSON_MAX (radix_position - 1, 0)) && + for (uint32_t i = 0; + bson_cmp_greater_us (significand_digits - i, + BSON_MAX (radix_position - 1, 0)) && (str_out - str) < BSON_DECIMAL128_STRING; i++) { *(str_out++) = *(significand_read++) + '0'; @@ -579,14 +581,18 @@ bson_decimal128_from_string_w_len (const char *string, /* IN */ #else #define SSCANF sscanf #endif - int read_exponent = SSCANF (++str_read, "%d%n", &exponent, &nread); + int64_t temp_exponent = 0; + int read_exponent = + SSCANF (++str_read, "%" SCNd64 "%n", &temp_exponent, &nread); str_read += nread; - if (!read_exponent || nread == 0) { + if (!read_exponent || nread == 0 || + !bson_in_range_int32_t_signed (temp_exponent)) { BSON_DECIMAL128_SET_NAN (*dec); return false; } + exponent = (int32_t) temp_exponent; #undef SSCANF } @@ -623,10 +629,12 @@ bson_decimal128_from_string_w_len (const char *string, /* IN */ /* to represent user input */ /* Overflow prevention */ - if (exponent <= radix_position && radix_position - exponent > (1 << 14)) { + if (bson_cmp_less_equal_su (exponent, radix_position) && + bson_cmp_greater_us (radix_position, exponent + (1 << 14))) { exponent = BSON_DECIMAL128_EXPONENT_MIN; } else { - exponent -= radix_position; + BSON_ASSERT (bson_in_range_unsigned (int32_t, radix_position)); + exponent -= (int32_t) radix_position; } /* Attempt to normalize the exponent */ diff --git a/src/bson/bson-decimal128.h b/src/bson/bson-decimal128.h index 51ec46fe..0ab72889 100644 --- a/src/bson/bson-decimal128.h +++ b/src/bson/bson-decimal128.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_DECIMAL128_H @@ -23,9 +23,9 @@ #include -#include "bson-macros.h" -#include "bson-config.h" -#include "bson-types.h" +#include +#include +#include /** diff --git a/src/bson/bson-endian.h b/src/bson/bson-endian.h index 1acb5479..85ae95fb 100644 --- a/src/bson/bson-endian.h +++ b/src/bson/bson-endian.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_ENDIAN_H @@ -25,9 +25,9 @@ #include #endif -#include "bson-config.h" -#include "bson-macros.h" -#include "bson-compat.h" +#include +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-error.c b/src/bson/bson-error.c index d16b5fae..0c6257b1 100644 --- a/src/bson/bson-error.c +++ b/src/bson/bson-error.c @@ -18,12 +18,17 @@ #include #include -#include "bson-compat.h" -#include "bson-config.h" -#include "bson-error.h" -#include "bson-memory.h" -#include "bson-string.h" -#include "bson-types.h" +#include +#include +#include +#include +#include +#include + +// See `bson_strerror_r()` definition below. +#if !defined(_WIN32) && !defined(__APPLE__) +#include // uselocale() +#endif /* @@ -98,23 +103,75 @@ bson_set_error (bson_error_t *error, /* OUT */ */ char * -bson_strerror_r (int err_code, /* IN */ - char *buf, /* IN */ - size_t buflen) /* IN */ +bson_strerror_r (int err_code, /* IN */ + char *buf BSON_MAYBE_UNUSED, /* IN */ + size_t buflen BSON_MAYBE_UNUSED) /* IN */ { static const char *unknown_msg = "Unknown error"; char *ret = NULL; #if defined(_WIN32) + // Windows does not provide `strerror_l` or `strerror_r`, but it does + // unconditionally provide `strerror_s`. if (strerror_s (buf, buflen, err_code) != 0) { ret = buf; } -#elif defined(__GNUC__) && defined(_GNU_SOURCE) - ret = strerror_r (err_code, buf, buflen); -#else /* XSI strerror_r */ - if (strerror_r (err_code, buf, buflen) == 0) { - ret = buf; +#elif defined(_AIX) + // AIX does not provide strerror_l, and its strerror_r isn't glibc's. + // But it does provide a glibc compatible one called __linux_strerror_r + ret = __linux_strerror_r (err_code, buf, buflen); +#elif defined(__APPLE__) + // Apple does not provide `strerror_l`, but it does unconditionally provide + // the XSI-compliant `strerror_r`, but only when compiling with Apple Clang. + // GNU extensions may still be a problem if we are being compiled with GCC on + // Apple. Avoid the compatibility headaches with GNU extensions and the musl + // library by assuming the implementation will not cause UB when reading the + // error message string even when `strerror_r` fails, as encouraged (but not + // required) by the POSIX spec (see: + // https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html#tag_16_574_08). + (void) strerror_r (err_code, buf, buflen); +#elif defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700 + // The behavior (of `strerror_l`) is undefined if the locale argument to + // `strerror_l()` is the special locale object LC_GLOBAL_LOCALE or is not a + // valid locale object handle. + locale_t locale = uselocale ((locale_t) 0); + // No need to test for error (it can only be [EINVAL]). + if (locale == LC_GLOBAL_LOCALE) { + // Only use our own locale if a thread-local locale was not already set. + // This is just to satisfy `strerror_l`. We do NOT want to unconditionally + // set a thread-local locale. + locale = newlocale (LC_MESSAGES_MASK, "C", (locale_t) 0); } + BSON_ASSERT (locale != LC_GLOBAL_LOCALE); + + // Avoid `strerror_r` compatibility headaches with GNU extensions and the + // musl library by using `strerror_l` instead. Furthermore, `strerror_r` is + // scheduled to be marked as obsolete in favor of `strerror_l` in the + // upcoming POSIX Issue 8 (see: + // https://www.austingroupbugs.net/view.php?id=655). + // + // POSIX Spec: since strerror_l() is required to return a string for some + // errors, an application wishing to check for all error situations should + // set errno to 0, then call strerror_l(), then check errno. + if (locale != (locale_t) 0) { + errno = 0; + ret = strerror_l (err_code, locale); + + if (errno != 0) { + ret = NULL; + } + + freelocale (locale); + } else { + // Could not obtain a valid `locale_t` object to satisfy `strerror_l`. + // Fallback to `bson_strncpy` below. + } +#elif defined(_GNU_SOURCE) + // Unlikely, but continue supporting use of GNU extension in cases where the + // C Driver is being built without _XOPEN_SOURCE=700. + ret = strerror_r (err_code, buf, buflen); +#else +#error "Unable to find a supported strerror_r candidate" #endif if (!ret) { diff --git a/src/bson/bson-error.h b/src/bson/bson-error.h index 24b6b97f..7bfb21bf 100644 --- a/src/bson/bson-error.h +++ b/src/bson/bson-error.h @@ -14,16 +14,16 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_ERROR_H #define BSON_ERROR_H -#include "bson-compat.h" -#include "bson-macros.h" -#include "bson-types.h" +#include +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-iso8601-private.h b/src/bson/bson-iso8601-private.h index df39ccb4..f76cb56a 100644 --- a/src/bson/bson-iso8601-private.h +++ b/src/bson/bson-iso8601-private.h @@ -14,16 +14,16 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_ISO8601_PRIVATE_H #define BSON_ISO8601_PRIVATE_H -#include "bson-compat.h" -#include "bson-macros.h" -#include "bson-string.h" +#include +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-iso8601.c b/src/bson/bson-iso8601.c index 0ff6b029..2161f85d 100644 --- a/src/bson/bson-iso8601.c +++ b/src/bson/bson-iso8601.c @@ -15,12 +15,12 @@ */ -#include "bson-compat.h" -#include "bson-macros.h" -#include "bson-error.h" -#include "bson-iso8601-private.h" -#include "bson-json.h" -#include "bson-timegm-private.h" +#include +#include +#include +#include +#include +#include static bool diff --git a/src/bson/bson-iter.c b/src/bson/bson-iter.c index 7b4630f9..a71b2b59 100644 --- a/src/bson/bson-iter.c +++ b/src/bson/bson-iter.c @@ -15,10 +15,10 @@ */ -#include "bson-iter.h" -#include "bson-config.h" -#include "bson-decimal128.h" -#include "bson-types.h" +#include +#include +#include +#include #define ITER_TYPE(i) ((bson_type_t) * ((i)->raw + (i)->type)) @@ -110,8 +110,13 @@ bson_iter_init_from_data (bson_iter_t *iter, /* OUT */ return false; } + if (BSON_UNLIKELY (!bson_in_range_unsigned (uint32_t, length))) { + memset (iter, 0, sizeof *iter); + return false; + } + iter->raw = (uint8_t *) data; - iter->len = length; + iter->len = (uint32_t) length; iter->off = 0; iter->type = 0; iter->key = 0; diff --git a/src/bson/bson-iter.h b/src/bson/bson-iter.h index 92e1968f..22af2e45 100644 --- a/src/bson/bson-iter.h +++ b/src/bson/bson-iter.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_ITER_H @@ -22,9 +22,9 @@ #include "bson.h" -#include "bson-endian.h" -#include "bson-macros.h" -#include "bson-types.h" +#include +#include +#include BSON_BEGIN_DECLS @@ -109,11 +109,15 @@ bson_iter_value (bson_iter_t *iter); static BSON_INLINE uint32_t bson_iter_utf8_len_unsafe (const bson_iter_t *iter) { - int32_t val; + uint32_t raw; + memcpy (&raw, iter->raw + iter->d1, sizeof (raw)); - memcpy (&val, iter->raw + iter->d1, sizeof (val)); - val = BSON_UINT32_FROM_LE (val); - return BSON_MAX (0, val - 1); + const uint32_t native = BSON_UINT32_FROM_LE (raw); + + int32_t len; + memcpy (&len, &native, sizeof (len)); + + return len <= 0 ? 0u : (uint32_t) (len - 1); } @@ -242,10 +246,14 @@ bson_iter_int32 (const bson_iter_t *iter); static BSON_INLINE int32_t bson_iter_int32_unsafe (const bson_iter_t *iter) { - int32_t val; + uint32_t raw; + memcpy (&raw, iter->raw + iter->d1, sizeof (raw)); - memcpy (&val, iter->raw + iter->d1, sizeof (val)); - return BSON_UINT32_FROM_LE (val); + const uint32_t native = BSON_UINT32_FROM_LE (raw); + + int32_t res; + memcpy (&res, &native, sizeof (res)); + return res; } @@ -268,10 +276,14 @@ bson_iter_as_int64 (const bson_iter_t *iter); static BSON_INLINE int64_t bson_iter_int64_unsafe (const bson_iter_t *iter) { - int64_t val; + uint64_t raw; + memcpy (&raw, iter->raw + iter->d1, sizeof (raw)); - memcpy (&val, iter->raw + iter->d1, sizeof (val)); - return BSON_UINT64_FROM_LE (val); + const uint64_t native = BSON_UINT64_FROM_LE (raw); + + int64_t res; + memcpy (&res, &native, sizeof (res)); + return res; } @@ -407,7 +419,7 @@ bson_iter_time_t (const bson_iter_t *iter); static BSON_INLINE time_t bson_iter_time_t_unsafe (const bson_iter_t *iter) { - return (time_t) (bson_iter_int64_unsafe (iter) / 1000UL); + return (time_t) (bson_iter_int64_unsafe (iter) / 1000); } @@ -428,10 +440,11 @@ bson_iter_timeval_unsafe (const bson_iter_t *iter, struct timeval *tv) int64_t value = bson_iter_int64_unsafe (iter); #ifdef BSON_OS_WIN32 tv->tv_sec = (long) (value / 1000); + tv->tv_usec = (long) (value % 1000) * 1000; #else - tv->tv_sec = (suseconds_t) (value / 1000); + tv->tv_sec = (time_t) (value / 1000); + tv->tv_usec = (suseconds_t) (value % 1000) * 1000; #endif - tv->tv_usec = (value % 1000) * 1000; } @@ -511,7 +524,8 @@ bson_iter_overwrite_double (bson_iter_t *iter, double value); BSON_EXPORT (void) -bson_iter_overwrite_decimal128 (bson_iter_t *iter, const bson_decimal128_t *value); +bson_iter_overwrite_decimal128 (bson_iter_t *iter, + const bson_decimal128_t *value); BSON_EXPORT (void) diff --git a/src/bson/bson-json-private.h b/src/bson/bson-json-private.h index 9f51dcbd..7a562a2b 100644 --- a/src/bson/bson-json-private.h +++ b/src/bson/bson-json-private.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_JSON_PRIVATE_H #define BSON_JSON_PRIVATE_H @@ -23,6 +23,7 @@ struct _bson_json_opts_t { bson_json_mode_t mode; int32_t max_len; + bool is_outermost_array; }; diff --git a/src/bson/bson-json.c b/src/bson/bson-json.c index e1f0fa72..c6624b71 100644 --- a/src/bson/bson-json.c +++ b/src/bson/bson-json.c @@ -21,10 +21,10 @@ #include #include "bson.h" -#include "bson-config.h" -#include "bson-json.h" -#include "bson-json-private.h" -#include "bson-iso8601-private.h" +#include +#include +#include +#include #include "common-b64-private.h" #include "jsonsl/jsonsl.h" @@ -394,8 +394,11 @@ bson_json_opts_new (bson_json_mode_t mode, int32_t max_len) bson_json_opts_t *opts; opts = (bson_json_opts_t *) bson_malloc (sizeof *opts); - opts->mode = mode; - opts->max_len = max_len; + *opts = (bson_json_opts_t){ + .mode = mode, + .max_len = max_len, + .is_outermost_array = false, + }; return opts; } @@ -628,7 +631,13 @@ _bson_json_read_integer (bson_json_reader_t *reader, uint64_t val, int64_t sign) bson_append_int32 ( STACK_BSON_CHILD, key, (int) len, (int) (val * sign)); } else if (sign == -1) { +#if defined(_WIN32) && !defined(__MINGW32__) + // Unary negation of unsigned integer is deliberate. +#pragma warning(suppress : 4146) bson_append_int64 (STACK_BSON_CHILD, key, (int) len, (int64_t) -val); +#else + bson_append_int64 (STACK_BSON_CHILD, key, (int) len, (int64_t) -val); +#endif // defined(_WIN32) && !defined(__MINGW32__) } else { bson_append_int64 (STACK_BSON_CHILD, key, (int) len, (int64_t) val); } @@ -735,33 +744,19 @@ _bson_json_parse_double (bson_json_reader_t *reader, *d = strtod (val, NULL); #ifdef _MSC_VER + const double pos_inf = INFINITY; + const double neg_inf = -pos_inf; + /* Microsoft's strtod parses "NaN", "Infinity", "-Infinity" as 0 */ if (*d == 0.0) { if (!_strnicmp (val, "nan", vlen)) { -#ifdef NAN *d = NAN; -#else - /* Visual Studio 2010 doesn't define NAN or INFINITY - * https://msdn.microsoft.com/en-us/library/w22adx1s(v=vs.100).aspx */ - unsigned long nan[2] = {0xffffffff, 0x7fffffff}; - *d = *(double *) nan; -#endif return true; } else if (!_strnicmp (val, "infinity", vlen)) { -#ifdef INFINITY - *d = INFINITY; -#else - unsigned long inf[2] = {0x00000000, 0x7ff00000}; - *d = *(double *) inf; -#endif + *d = pos_inf; return true; } else if (!_strnicmp (val, "-infinity", vlen)) { -#ifdef INFINITY - *d = -INFINITY; -#else - unsigned long inf[2] = {0x00000000, 0xfff00000}; - *d = *(double *) inf; -#endif + *d = neg_inf; return true; } } @@ -831,7 +826,7 @@ static bool _unhexlify_uuid (const char *uuid, uint8_t *out, size_t max) { unsigned int byte; - int x = 0; + size_t x = 0; int i = 0; BSON_ASSERT (strlen (uuid) == 32); @@ -1129,9 +1124,9 @@ _bson_json_read_string (bson_json_reader_t *reader, /* IN */ } break; case BSON_JSON_LF_DECIMAL128: { bson_decimal128_t decimal128; - bson_decimal128_from_string (val_w_null, &decimal128); - if (bson->read_state == BSON_JSON_IN_BSON_TYPE) { + if (bson_decimal128_from_string (val_w_null, &decimal128) && + bson->read_state == BSON_JSON_IN_BSON_TYPE) { bson->bson_type_data.v_decimal128.value = decimal128; } else { goto BAD_PARSE; @@ -1186,8 +1181,9 @@ _bson_json_read_start_map (bson_json_reader_t *reader) /* IN */ * expected a legacy Binary format. now we see the second "{", so * backtrack and parse $type query operator. */ bson->read_state = BSON_JSON_IN_START_MAP; + BSON_ASSERT (bson_in_range_unsigned (int, len)); STACK_PUSH_DOC (bson_append_document_begin ( - STACK_BSON_PARENT, key, len, STACK_BSON_CHILD)); + STACK_BSON_PARENT, key, (int) len, STACK_BSON_CHILD)); _bson_json_save_map_key (bson, (const uint8_t *) "$type", 5); break; case BSON_JSON_LF_CODE: @@ -1301,7 +1297,7 @@ _bson_json_read_code_or_scope_key (bson_json_reader_bson_t *bson, /* save the key, e.g. {"key": {"$code": "return x", "$scope":{"x":1}}}, * in case it is overwritten while parsing scope sub-object */ _bson_json_buf_set ( - &bson->code_data.key_buf, bson->key_buf.buf, bson->key_buf.len); + &bson->code_data.key_buf, bson->key, bson->key_buf.len); } if (is_scope) { @@ -1405,7 +1401,7 @@ _bson_json_read_map_key (bson_json_reader_t *reader, /* IN */ { /* start parsing "key": {"$dbPointer": {...}}, save "key" for later */ _bson_json_buf_set ( - &bson->dbpointer_key, bson->key_buf.buf, bson->key_buf.len); + &bson->dbpointer_key, bson->key, bson->key_buf.len); bson->bson_type = BSON_TYPE_DBPOINTER; bson->read_state = BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP; @@ -2233,8 +2229,11 @@ bson_json_reader_read (bson_json_reader_t *reader, /* IN */ /* accumulate a key or string value */ if (reader->json_text_pos != -1) { - if (reader->json_text_pos < reader->json->pos) { - accum = BSON_MIN (reader->json->pos - reader->json_text_pos, r); + if (bson_cmp_less_su (reader->json_text_pos, reader->json->pos)) { + BSON_ASSERT ( + bson_in_range_unsigned (ssize_t, reader->json->pos)); + accum = BSON_MIN ( + (ssize_t) reader->json->pos - reader->json_text_pos, r); /* if this chunk stopped mid-token, buf_offset is how far into * our current chunk the token begins. */ buf_offset = AT_LEAST_0 (reader->json_text_pos - start_pos); @@ -2339,6 +2338,14 @@ bson_json_reader_destroy (bson_json_reader_t *reader) /* IN */ } +void +bson_json_opts_set_outermost_array (bson_json_opts_t *opts, + bool is_outermost_array) +{ + opts->is_outermost_array = is_outermost_array; +} + + typedef struct { const uint8_t *data; size_t len; diff --git a/src/bson/bson-json.h b/src/bson/bson-json.h index 20fab573..9efc8c34 100644 --- a/src/bson/bson-json.h +++ b/src/bson/bson-json.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_JSON_H @@ -61,7 +61,9 @@ BSON_EXPORT (bson_json_opts_t *) bson_json_opts_new (bson_json_mode_t mode, int32_t max_len); BSON_EXPORT (void) bson_json_opts_destroy (bson_json_opts_t *opts); - +BSON_EXPORT (void) +bson_json_opts_set_outermost_array (bson_json_opts_t *opts, + bool is_outermost_array); typedef ssize_t (*bson_json_reader_cb) (void *handle, uint8_t *buf, diff --git a/src/bson/bson-keys.c b/src/bson/bson-keys.c index ce726093..0f3f7355 100644 --- a/src/bson/bson-keys.c +++ b/src/bson/bson-keys.c @@ -17,8 +17,8 @@ #include -#include "bson-keys.h" -#include "bson-string.h" +#include +#include static const char *gUint32Strs[] = { @@ -138,7 +138,10 @@ static const char *gUint32Strs[] = { * @size: Size of @str. * * Returns: - * The number of bytes in the resulting string. + * The number of bytes in the resulting string excluding the NULL + * terminator. If the output requires more than @size bytes, then @size + * bytes are written and the result is the number of bytes required + * (excluding the NULL terminator) * * Side effects: * None. diff --git a/src/bson/bson-keys.h b/src/bson/bson-keys.h index da3efade..ba4c0f75 100644 --- a/src/bson/bson-keys.h +++ b/src/bson/bson-keys.h @@ -14,15 +14,15 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_KEYS_H #define BSON_KEYS_H -#include "bson-macros.h" -#include "bson-types.h" +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-macros.h b/src/bson/bson-macros.h index e7a3097a..d566713a 100644 --- a/src/bson/bson-macros.h +++ b/src/bson/bson-macros.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_MACROS_H @@ -27,7 +27,7 @@ #include #endif -#include "bson-config.h" +#include #if BSON_OS == 1 @@ -66,11 +66,10 @@ /* Decorate public functions: - * - if BSON_STATIC, we're compiling a program that uses libbson as a static - * library, don't decorate functions - * - else if BSON_COMPILATION, we're compiling a static or shared libbson, mark - * public functions for export from the shared lib (which has no effect on - * the static lib) + * - if BSON_STATIC, we're compiling a static libbson or a program + * that uses libbson as a static library. Don't decorate functions. + * - else if BSON_COMPILATION, we're compiling a shared libbson, mark + * public functions for export from the shared lib * - else, we're compiling a program that uses libbson as a shared library, * mark public functions as DLL imports for Microsoft Visual C */ @@ -82,9 +81,9 @@ #ifdef BSON_STATIC #define BSON_API #elif defined(BSON_COMPILATION) -#define BSON_API __declspec(dllexport) +#define BSON_API __declspec (dllexport) #else -#define BSON_API __declspec(dllimport) +#define BSON_API __declspec (dllimport) #endif #define BSON_CALL __cdecl @@ -141,13 +140,15 @@ #define BSON_ABS(a) (((a) < 0) ? ((a) * -1) : (a)) #endif -#if __STDC_VERSION__ >= 201112L -#define BSON_ALIGNOF(expr) _Alignof(expr) +#if defined(__cplusplus) && (__cplusplus >= 201103L || defined(_MSVC_LANG)) +#define BSON_ALIGNOF(expr) alignof (expr) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define BSON_ALIGNOF(expr) _Alignof (expr) #else #if defined(_MSC_VER) -#define BSON_ALIGNOF(expr) __alignof(expr) +#define BSON_ALIGNOF(expr) __alignof (expr) #else -#define BSON_ALIGNOF(expr) __alignof__(expr) +#define BSON_ALIGNOF(expr) __alignof__ (expr) #endif #endif // __STDC_VERSION__ >= 201112L @@ -164,7 +165,7 @@ #ifdef BSON_EXTRA_ALIGN #if defined(_MSC_VER) -#define BSON_ALIGNED_BEGIN(_N) __declspec(align (_N)) +#define BSON_ALIGNED_BEGIN(_N) __declspec (align (_N)) #define BSON_ALIGNED_END(_N) #else #define BSON_ALIGNED_BEGIN(_N) @@ -172,7 +173,7 @@ #endif #else #if defined(_MSC_VER) -#define BSON_ALIGNED_BEGIN(_N) __declspec(align (BSON_ALIGN_OF_PTR)) +#define BSON_ALIGNED_BEGIN(_N) __declspec (align (BSON_ALIGN_OF_PTR)) #define BSON_ALIGNED_END(_N) #else #define BSON_ALIGNED_BEGIN(_N) @@ -189,8 +190,6 @@ #if defined(_MSC_VER) #define BSON_FUNC __FUNCTION__ -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L -#define BSON_FUNC __FUNCTION__ #else #define BSON_FUNC __func__ #endif @@ -323,7 +322,7 @@ #define BSON_ENSURE_ARRAY_PARAM_SIZE(_n) #define BSON_TYPEOF decltype #else -#define BSON_ENSURE_ARRAY_PARAM_SIZE(_n) static(_n) +#define BSON_ENSURE_ARRAY_PARAM_SIZE(_n) static (_n) #define BSON_TYPEOF typeof #endif diff --git a/src/bson/bson-md5.c b/src/bson/bson-md5.c index 71d7a54c..5c736cfc 100644 --- a/src/bson/bson-md5.c +++ b/src/bson/bson-md5.c @@ -1,6 +1,6 @@ -#include "bson-compat.h" +#include -#include "bson-md5.h" +#include #include "common-md5-private.h" diff --git a/src/bson/bson-md5.h b/src/bson/bson-md5.h index 213fc5d4..46ca8b98 100644 --- a/src/bson/bson-md5.h +++ b/src/bson/bson-md5.h @@ -53,14 +53,14 @@ * specified in libbson. */ -#include "bson-prelude.h" +#include #ifndef BSON_MD5_H #define BSON_MD5_H -#include "bson-endian.h" +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-memory.c b/src/bson/bson-memory.c index 40d06454..2c93018a 100644 --- a/src/bson/bson-memory.c +++ b/src/bson/bson-memory.c @@ -20,9 +20,9 @@ #include #include -#include "bson-atomic.h" -#include "bson-config.h" -#include "bson-memory.h" +#include +#include +#include // Ensure size of exported structs are stable. @@ -40,7 +40,10 @@ _aligned_alloc_impl (size_t alignment, size_t num_bytes) #elif defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L { void *mem = NULL; - (void) posix_memalign (&mem, alignment, num_bytes); + + // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425. + BSON_MAYBE_UNUSED int ret = posix_memalign (&mem, alignment, num_bytes); + return mem; } #else @@ -148,7 +151,7 @@ bson_malloc0 (size_t num_bytes) /* IN */ /* *-------------------------------------------------------------------------- * - * bson_aligned_malloc -- + * bson_aligned_alloc -- * * Allocates @num_bytes of memory with an alignment of @alignment and * returns a pointer to it. If malloc failed to allocate the memory, diff --git a/src/bson/bson-memory.h b/src/bson/bson-memory.h index a0f8c234..99470701 100644 --- a/src/bson/bson-memory.h +++ b/src/bson/bson-memory.h @@ -14,15 +14,15 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_MEMORY_H #define BSON_MEMORY_H -#include "bson-macros.h" -#include "bson-types.h" +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-oid.c b/src/bson/bson-oid.c index 513d0626..8834d7d3 100644 --- a/src/bson/bson-oid.c +++ b/src/bson/bson-oid.c @@ -14,16 +14,16 @@ * limitations under the License. */ -#include "bson-compat.h" +#include #include #include #include #include -#include "bson-context-private.h" -#include "bson-oid.h" -#include "bson-string.h" +#include +#include +#include /* @@ -32,7 +32,7 @@ * to hex formatted ASCII. Performing two characters at a time roughly * reduces the number of operations by one-half. */ -static const uint16_t gHexCharPairs[] = { +BSON_MAYBE_UNUSED static const uint16_t gHexCharPairs[] = { #if BSON_BYTE_ORDER == BSON_BIG_ENDIAN 12336, 12337, 12338, 12339, 12340, 12341, 12342, 12343, 12344, 12345, 12385, 12386, 12387, 12388, 12389, 12390, 12592, 12593, 12594, 12595, 12596, 12597, diff --git a/src/bson/bson-oid.h b/src/bson/bson-oid.h index 8586df8e..5f4426a5 100644 --- a/src/bson/bson-oid.h +++ b/src/bson/bson-oid.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_OID_H @@ -23,10 +23,10 @@ #include -#include "bson-context.h" -#include "bson-macros.h" -#include "bson-types.h" -#include "bson-endian.h" +#include +#include +#include +#include BSON_BEGIN_DECLS @@ -51,8 +51,8 @@ bson_oid_init_from_data (bson_oid_t *oid, const uint8_t *data); BSON_EXPORT (void) bson_oid_init_from_string (bson_oid_t *oid, const char *str); BSON_EXPORT (void) -bson_oid_init_sequence (bson_oid_t *oid, - bson_context_t *context) BSON_GNUC_DEPRECATED; +bson_oid_init_sequence (bson_oid_t *oid, bson_context_t *context) + BSON_GNUC_DEPRECATED_FOR (bson_oid_init); BSON_EXPORT (void) bson_oid_to_string (const bson_oid_t *oid, char str[25]); diff --git a/src/bson/bson-private.h b/src/bson/bson-private.h index 8154da68..121a5ff2 100644 --- a/src/bson/bson-private.h +++ b/src/bson/bson-private.h @@ -14,16 +14,16 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_PRIVATE_H #define BSON_PRIVATE_H -#include "bson-macros.h" -#include "bson-memory.h" -#include "bson-types.h" +#include +#include +#include #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) diff --git a/src/bson/bson-reader.c b/src/bson/bson-reader.c index e0a5c97d..3250d14b 100644 --- a/src/bson/bson-reader.c +++ b/src/bson/bson-reader.c @@ -27,8 +27,8 @@ #include #include -#include "bson-reader.h" -#include "bson-memory.h" +#include +#include typedef enum { diff --git a/src/bson/bson-reader.h b/src/bson/bson-reader.h index 2fc5db46..7c818659 100644 --- a/src/bson/bson-reader.h +++ b/src/bson/bson-reader.h @@ -14,16 +14,16 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_READER_H #define BSON_READER_H -#include "bson-compat.h" -#include "bson-oid.h" -#include "bson-types.h" +#include +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-string.c b/src/bson/bson-string.c index 68c6ef20..958fd106 100644 --- a/src/bson/bson-string.c +++ b/src/bson/bson-string.c @@ -18,11 +18,11 @@ #include #include -#include "bson-compat.h" -#include "bson-config.h" -#include "bson-string.h" -#include "bson-memory.h" -#include "bson-utf8.h" +#include +#include +#include +#include +#include #ifdef BSON_HAVE_STRINGS_H #include @@ -77,7 +77,6 @@ bson_string_new (const char *str) /* IN */ if (str) { memcpy (ret->str, str, ret->len); } - ret->str[ret->len] = '\0'; ret->str[ret->len] = '\0'; @@ -90,7 +89,9 @@ bson_string_free (bson_string_t *string, /* IN */ { char *ret = NULL; - BSON_ASSERT (string); + if (!string) { + return NULL; + } if (!free_segment) { ret = string->str; @@ -472,11 +473,11 @@ bson_strndup (const char *str, /* IN */ void bson_strfreev (char **str) /* IN */ { - int i; - if (str) { - for (i = 0; str[i]; i++) - bson_free (str[i]); + for (char **ptr = str; *ptr != NULL; ++ptr) { + bson_free (*ptr); + } + bson_free (str); } } diff --git a/src/bson/bson-string.h b/src/bson/bson-string.h index dbf9497b..467a4567 100644 --- a/src/bson/bson-string.h +++ b/src/bson/bson-string.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_STRING_H @@ -23,8 +23,8 @@ #include -#include "bson-macros.h" -#include "bson-types.h" +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-timegm-private.h b/src/bson/bson-timegm-private.h index 89d57b54..93d9a8e7 100644 --- a/src/bson/bson-timegm-private.h +++ b/src/bson/bson-timegm-private.h @@ -14,15 +14,15 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_TIMEGM_PRIVATE_H #define BSON_TIMEGM_PRIVATE_H -#include "bson-compat.h" -#include "bson-macros.h" +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-timegm.c b/src/bson/bson-timegm.c index 404cc368..cea7b2f5 100644 --- a/src/bson/bson-timegm.c +++ b/src/bson/bson-timegm.c @@ -10,9 +10,9 @@ ** and struct tm by A. Jesse Jiryu Davis for MongoDB, Inc. */ -#include "bson-compat.h" -#include "bson-macros.h" -#include "bson-timegm-private.h" +#include +#include +#include #include "errno.h" #include "string.h" @@ -34,22 +34,21 @@ #if !defined _Noreturn && \ (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112) #if 2 < __GNUC__ + (8 <= __GNUC_MINOR__) -#define _Noreturn __attribute__((__noreturn__)) +#define _Noreturn __attribute__ ((__noreturn__)) #else #define _Noreturn #endif #endif -#if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901) && \ - !defined restrict +#if !defined(__STDC_VERSION__) && !defined restrict #define restrict /* empty */ #endif #ifdef __clang__ -/*IGNORE*/ #pragma clang diagnostic push -/*IGNORE*/ #pragma clang diagnostic ignored "-Wunknown-pragmas" -/*IGNORE*/ #pragma clang diagnostic push -/*IGNORE*/ #pragma clang diagnostic ignored "-Wshift-negative-value" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wshift-negative-value" #endif /* The minimum and maximum finite time values. */ @@ -57,8 +56,8 @@ static int64_t const time_t_min = INT64_MIN; static int64_t const time_t_max = INT64_MAX; #ifdef __clang__ -/*IGNORE*/ #pragma clang diagnostic pop -/*IGNORE*/ #pragma clang diagnostic pop +#pragma clang diagnostic pop +#pragma clang diagnostic pop #endif #ifndef TZ_MAX_TIMES @@ -181,7 +180,7 @@ struct ttinfo { /* time type information */ }; struct lsinfo { /* leap second information */ - int64_t ls_trans; /* transition time */ + int64_t ls_trans; /* transition time */ int_fast64_t ls_corr; /* correction to apply */ }; @@ -226,41 +225,53 @@ struct rule { */ static void -gmtload (struct state *sp); +gmtload (struct state *const sp); static struct bson_tm * -gmtsub (const int64_t *timep, int_fast32_t offset, struct bson_tm *tmp); +gmtsub (const int64_t *const timep, + const int_fast32_t offset, + struct bson_tm *const tmp); static int64_t -increment_overflow (int64_t *number, int64_t delta); +increment_overflow (int64_t *const ip, int64_t j); static int64_t -leaps_thru_end_of (int64_t y) ATTRIBUTE_PURE; +leaps_thru_end_of (const int64_t y) ATTRIBUTE_PURE; static int64_t -increment_overflow32 (int_fast32_t *number, int64_t delta); +increment_overflow32 (int_fast32_t *const lp, int64_t const m); static int64_t -normalize_overflow32 (int_fast32_t *tensptr, int64_t *unitsptr, int64_t base); +normalize_overflow32 (int_fast32_t *const tensptr, + int64_t *const unitsptr, + const int64_t base); static int64_t -normalize_overflow (int64_t *tensptr, int64_t *unitsptr, int64_t base); +normalize_overflow (int64_t *const tensptr, + int64_t *const unitsptr, + const int64_t base); static int64_t -time1 (struct bson_tm *tmp, - struct bson_tm *(*funcp) (const int64_t *, int_fast32_t, struct bson_tm *), - int_fast32_t offset); +time1 (struct bson_tm *const tmp, + struct bson_tm *(*const funcp) (const int64_t *, + int_fast32_t, + struct bson_tm *), + const int_fast32_t offset); static int64_t -time2 (struct bson_tm *tmp, - struct bson_tm *(*funcp) (const int64_t *, int_fast32_t, struct bson_tm *), - int_fast32_t offset, - int64_t *okayp); +time2 (struct bson_tm *const tmp, + struct bson_tm *(*const funcp) (const int64_t *, + int_fast32_t, + struct bson_tm *), + const int_fast32_t offset, + int64_t *const okayp); static int64_t -time2sub (struct bson_tm *tmp, - struct bson_tm *(*funcp) (const int64_t *, int_fast32_t, struct bson_tm *), - int_fast32_t offset, - int64_t *okayp, - int64_t do_norm_secs); +time2sub (struct bson_tm *const tmp, + struct bson_tm *(*const funcp) (const int64_t *, + int_fast32_t, + struct bson_tm *), + const int_fast32_t offset, + int64_t *const okayp, + const int64_t do_norm_secs); static struct bson_tm * -timesub (const int64_t *timep, - int_fast32_t offset, - const struct state *sp, - struct bson_tm *tmp); +timesub (const int64_t *const timep, + const int_fast32_t offset, + const struct state *const sp, + struct bson_tm *const tmp); static int64_t -tmcomp (const struct bson_tm *atmp, const struct bson_tm *btmp); +tmcomp (const struct bson_tm *const atmp, const struct bson_tm *const btmp); static struct state gmtmem; #define gmtptr (&gmtmem) @@ -293,7 +304,7 @@ gmtsub (const int64_t *const timep, const int_fast32_t offset, struct bson_tm *const tmp) { - register struct bson_tm *result; + struct bson_tm *result; if (!gmt_is_set) { gmt_is_set = true; @@ -317,7 +328,7 @@ gmtsub (const int64_t *const timep, */ static int64_t -leaps_thru_end_of (register const int64_t y) +leaps_thru_end_of (const int64_t y) { return (y >= 0) ? (y / 4 - y / 100 + y / 400) : -(leaps_thru_end_of (-(y + 1)) + 1); @@ -326,18 +337,18 @@ leaps_thru_end_of (register const int64_t y) static struct bson_tm * timesub (const int64_t *const timep, const int_fast32_t offset, - register const struct state *const sp, - register struct bson_tm *const tmp) + const struct state *const sp, + struct bson_tm *const tmp) { - register const struct lsinfo *lp; - register int64_t tdays; - register int64_t idays; /* unsigned would be so 2003 */ - register int_fast64_t rem; + const struct lsinfo *lp; + int64_t tdays; + int64_t idays; /* unsigned would be so 2003 */ + int_fast64_t rem; int64_t y; - register const int *ip; - register int_fast64_t corr; - register int64_t hit; - register int64_t i; + const int (*ip)[MONSPERYEAR]; + int_fast64_t corr; + int64_t hit; + int64_t i; corr = 0; hit = 0; @@ -365,9 +376,9 @@ timesub (const int64_t *const timep, rem = *timep - tdays * SECSPERDAY; while (tdays < 0 || tdays >= year_lengths[isleap (y)]) { int64_t newy; - register int64_t tdelta; - register int64_t idelta; - register int64_t leapdays; + int64_t tdelta; + int64_t idelta; + int64_t leapdays; tdelta = tdays / DAYSPERLYEAR; idelta = tdelta; @@ -382,7 +393,7 @@ timesub (const int64_t *const timep, y = newy; } { - register int_fast32_t seconds; + int_fast32_t seconds; seconds = (int_fast32_t) (tdays * SECSPERDAY); tdays = seconds / SECSPERDAY; @@ -433,9 +444,12 @@ timesub (const int64_t *const timep, ** representation. This uses "... ??:59:60" et seq. */ tmp->tm_sec = (int64_t) (rem % SECSPERMIN) + hit; - ip = mon_lengths[isleap (y)]; - for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) - idays -= ip[tmp->tm_mon]; + ip = mon_lengths + (isleap (y) ? 1 : 0); + tmp->tm_mon = 0; + while (idays >= (*ip)[tmp->tm_mon]) { + idays -= (*ip)[tmp->tm_mon++]; + BSON_ASSERT (tmp->tm_mon < MONSPERYEAR); + } tmp->tm_mday = (int64_t) (idays + 1); tmp->tm_isdst = 0; #ifdef TM_GMTOFF @@ -464,7 +478,7 @@ timesub (const int64_t *const timep, static int64_t increment_overflow (int64_t *const ip, int64_t j) { - register int64_t const i = *ip; + int64_t const i = *ip; /* ** If i >= 0 there can only be overflow if i + j > INT_MAX @@ -481,18 +495,20 @@ increment_overflow (int64_t *const ip, int64_t j) static int64_t increment_overflow32 (int_fast32_t *const lp, int64_t const m) { - register int_fast32_t const l = *lp; + int_fast32_t const l = *lp; if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l)) return true; - *lp += m; + *lp += (int_fast32_t) m; return false; } static int64_t -normalize_overflow (int64_t *const tensptr, int64_t *const unitsptr, const int64_t base) +normalize_overflow (int64_t *const tensptr, + int64_t *const unitsptr, + const int64_t base) { - register int64_t tensdelta; + int64_t tensdelta; tensdelta = (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base); @@ -505,7 +521,7 @@ normalize_overflow32 (int_fast32_t *const tensptr, int64_t *const unitsptr, const int64_t base) { - register int64_t tensdelta; + int64_t tensdelta; tensdelta = (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base); @@ -514,10 +530,9 @@ normalize_overflow32 (int_fast32_t *const tensptr, } static int64_t -tmcomp (register const struct bson_tm *const atmp, - register const struct bson_tm *const btmp) +tmcomp (const struct bson_tm *const atmp, const struct bson_tm *const btmp) { - register int64_t result; + int64_t result; if (atmp->tm_year != btmp->tm_year) return atmp->tm_year < btmp->tm_year ? -1 : 1; @@ -531,18 +546,20 @@ tmcomp (register const struct bson_tm *const atmp, static int64_t time2sub (struct bson_tm *const tmp, - struct bson_tm *(*const funcp) (const int64_t *, int_fast32_t, struct bson_tm *), + struct bson_tm *(*const funcp) (const int64_t *, + int_fast32_t, + struct bson_tm *), const int_fast32_t offset, int64_t *const okayp, const int64_t do_norm_secs) { - register const struct state *sp; - register int64_t dir; - register int64_t i, j; - register int64_t saved_seconds; - register int_fast32_t li; - register int64_t lo; - register int64_t hi; + const struct state *sp; + int64_t dir; + int64_t i, j; + int64_t saved_seconds; + int_fast32_t li; + int64_t lo; + int64_t hi; int_fast32_t y; int64_t newt; int64_t t; @@ -700,7 +717,9 @@ time2sub (struct bson_tm *const tmp, static int64_t time2 (struct bson_tm *const tmp, - struct bson_tm *(*const funcp) (const int64_t *, int_fast32_t, struct bson_tm *), + struct bson_tm *(*const funcp) (const int64_t *, + int_fast32_t, + struct bson_tm *), const int_fast32_t offset, int64_t *const okayp) { @@ -717,15 +736,17 @@ time2 (struct bson_tm *const tmp, static int64_t time1 (struct bson_tm *const tmp, - struct bson_tm *(*const funcp) (const int64_t *, int_fast32_t, struct bson_tm *), + struct bson_tm *(*const funcp) (const int64_t *, + int_fast32_t, + struct bson_tm *), const int_fast32_t offset) { - register int64_t t; - register const struct state *sp; - register int64_t samei, otheri; - register int64_t sameind, otherind; - register int64_t i; - register int64_t nseen; + int64_t t; + const struct state *sp; + int64_t samei, otheri; + int64_t sameind, otherind; + int64_t i; + int64_t nseen; int64_t seen[TZ_MAX_TYPES]; int64_t types[TZ_MAX_TYPES]; int64_t okay; @@ -792,4 +813,3 @@ _bson_timegm (struct bson_tm *const tmp) tmp->tm_isdst = 0; return time1 (tmp, gmtsub, 0L); } - diff --git a/src/bson/bson-types.h b/src/bson/bson-types.h index 498d5432..fd62cec2 100644 --- a/src/bson/bson-types.h +++ b/src/bson/bson-types.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_TYPES_H @@ -24,10 +24,10 @@ #include #include -#include "bson-macros.h" -#include "bson-config.h" -#include "bson-compat.h" -#include "bson-endian.h" +#include +#include +#include +#include BSON_BEGIN_DECLS @@ -127,7 +127,7 @@ typedef struct _bson_json_opts_t bson_json_opts_t; BSON_ALIGNED_BEGIN (128) typedef struct _bson_t { uint32_t flags; /* Internal flags for the bson_t. */ uint32_t len; /* Length of BSON data. */ - char *canary; /* For valgrind check */ + char *canary; /* For leak checks. */ uint8_t padding[120 - sizeof (char *)]; } bson_t BSON_ALIGNED_END (128); #else @@ -273,6 +273,7 @@ typedef enum { BSON_SUBTYPE_MD5 = 0x05, BSON_SUBTYPE_ENCRYPTED = 0x06, BSON_SUBTYPE_COLUMN = 0x07, + BSON_SUBTYPE_SENSITIVE = 0x08, BSON_SUBTYPE_USER = 0x80, } bson_subtype_t; diff --git a/src/bson/bson-utf8.c b/src/bson/bson-utf8.c index e122ac31..ac7a1bdd 100644 --- a/src/bson/bson-utf8.c +++ b/src/bson/bson-utf8.c @@ -17,9 +17,9 @@ #include -#include "bson-memory.h" -#include "bson-string.h" -#include "bson-utf8.h" +#include +#include +#include /* @@ -118,8 +118,8 @@ bson_utf8_validate (const char *utf8, /* IN */ bson_unichar_t c; uint8_t first_mask; uint8_t seq_length; - unsigned i; - unsigned j; + size_t i; + size_t j; BSON_ASSERT (utf8); diff --git a/src/bson/bson-utf8.h b/src/bson/bson-utf8.h index a1f7dfcb..af085969 100644 --- a/src/bson/bson-utf8.h +++ b/src/bson/bson-utf8.h @@ -14,15 +14,15 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_UTF8_H #define BSON_UTF8_H -#include "bson-macros.h" -#include "bson-types.h" +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-value.c b/src/bson/bson-value.c index 44d5ccd6..63f43a0c 100644 --- a/src/bson/bson-value.c +++ b/src/bson/bson-value.c @@ -15,10 +15,10 @@ */ -#include "bson-memory.h" -#include "bson-string.h" -#include "bson-value.h" -#include "bson-oid.h" +#include +#include +#include +#include void @@ -54,7 +54,8 @@ bson_value_copy (const bson_value_t *src, /* IN */ dst->value.v_binary.data_len = src->value.v_binary.data_len; dst->value.v_binary.data = bson_malloc (src->value.v_binary.data_len); if (dst->value.v_binary.data_len) { - memcpy (dst->value.v_binary.data, src->value.v_binary.data, + memcpy (dst->value.v_binary.data, + src->value.v_binary.data, dst->value.v_binary.data_len); } break; diff --git a/src/bson/bson-value.h b/src/bson/bson-value.h index 39f0b0f5..41756907 100644 --- a/src/bson/bson-value.h +++ b/src/bson/bson-value.h @@ -14,15 +14,15 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_VALUE_H #define BSON_VALUE_H -#include "bson-macros.h" -#include "bson-types.h" +#include +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-version-functions.c b/src/bson/bson-version-functions.c index 2ddcc139..90406edb 100644 --- a/src/bson/bson-version-functions.c +++ b/src/bson/bson-version-functions.c @@ -15,8 +15,8 @@ */ -#include "bson-version.h" -#include "bson-version-functions.h" +#include +#include /** diff --git a/src/bson/bson-version-functions.h b/src/bson/bson-version-functions.h index feb33cdb..923dcf0d 100644 --- a/src/bson/bson-version-functions.h +++ b/src/bson/bson-version-functions.h @@ -15,13 +15,13 @@ */ -#include "bson-prelude.h" +#include #ifndef BSON_VERSION_FUNCTIONS_H #define BSON_VERSION_FUNCTIONS_H -#include "bson-types.h" +#include BSON_BEGIN_DECLS diff --git a/src/bson/bson-version.h b/src/bson/bson-version.h index 805e7c41..e7680b30 100644 --- a/src/bson/bson-version.h +++ b/src/bson/bson-version.h @@ -15,10 +15,11 @@ */ -#if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) +#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION) #error "Only can be included directly." #endif +// clang-format off #ifndef BSON_VERSION_H #define BSON_VERSION_H @@ -37,7 +38,7 @@ * * BSON minor version component (e.g. 2 if %BSON_VERSION is 1.2.3) */ -#define BSON_MINOR_VERSION (23) +#define BSON_MINOR_VERSION (26) /** @@ -53,14 +54,14 @@ * * BSON prerelease version component (e.g. pre if %BSON_VERSION is 1.2.3-pre) */ -#define BSON_PRERELEASE_VERSION (pre) +#define BSON_PRERELEASE_VERSION () /** * BSON_VERSION: * * BSON version. */ -#define BSON_VERSION (1.23.2-pre) +#define BSON_VERSION (1.26.2) /** @@ -69,7 +70,7 @@ * BSON version, encoded as a string, useful for printing and * concatenation. */ -#define BSON_VERSION_S "1.23.2-pre" +#define BSON_VERSION_S "1.26.2" /** @@ -90,7 +91,7 @@ * @micro: required micro version * * Compile-time version checking. Evaluates to %TRUE if the version - * of BSON is greater than the required one. + * of BSON is greater than or equal to the required one. */ #define BSON_CHECK_VERSION(major,minor,micro) \ (BSON_MAJOR_VERSION > (major) || \ diff --git a/src/bson/bson-writer.c b/src/bson/bson-writer.c index 5c7c16a6..b9d12941 100644 --- a/src/bson/bson-writer.c +++ b/src/bson/bson-writer.c @@ -15,8 +15,8 @@ */ -#include "bson-private.h" -#include "bson-writer.h" +#include +#include struct _bson_writer_t { diff --git a/src/bson/bson-writer.h b/src/bson/bson-writer.h index 6ff74b07..969a0497 100644 --- a/src/bson/bson-writer.h +++ b/src/bson/bson-writer.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "bson-prelude.h" +#include #ifndef BSON_WRITER_H diff --git a/src/bson/bson.c b/src/bson/bson.c index cad9e612..e1e530a0 100644 --- a/src/bson/bson.c +++ b/src/bson/bson.c @@ -16,11 +16,11 @@ #include "bson.h" -#include "bson-config.h" -#include "bson-private.h" -#include "bson-json-private.h" -#include "bson-string.h" -#include "bson-iso8601-private.h" +#include +#include +#include +#include +#include #include "common-b64-private.h" @@ -85,7 +85,8 @@ static char * _bson_as_json_visit_all (const bson_t *bson, size_t *length, bson_json_mode_t mode, - int32_t max_len); + int32_t max_len, + bool is_outermost_array); /* * Globals. @@ -2184,7 +2185,7 @@ bson_copy_to (const bson_t *src, bson_t *dst) if ((src->flags & BSON_FLAG_INLINE)) { #ifdef BSON_MEMCHECK dst->len = src->len; - dst->canary = malloc (1); + dst->canary = bson_malloc (1); memcpy (dst->padding, src->padding, sizeof dst->padding); #else memcpy (dst, src, sizeof *dst); @@ -2295,7 +2296,6 @@ bson_copy_to_excluding_noinit (const bson_t *src, va_end (args); } - void bson_destroy (bson_t *bson) { @@ -2993,12 +2993,13 @@ _bson_as_json_visit_after (const bson_iter_t *iter, const char *key, void *data) return false; } - if (state->str->len >= state->max_len) { + if (bson_cmp_greater_equal_us (state->str->len, state->max_len)) { state->max_len_reached = true; - if (state->str->len > state->max_len) { + if (bson_cmp_greater_us (state->str->len, state->max_len)) { + BSON_ASSERT (bson_in_range_signed (uint32_t, state->max_len)); /* Truncate string to maximum length */ - bson_string_truncate (state->str, state->max_len); + bson_string_truncate (state->str, (uint32_t) state->max_len); } return true; @@ -3106,10 +3107,12 @@ _bson_as_json_visit_codewscope (const bson_iter_t *iter, /* Encode scope with the same mode */ if (state->max_len != BSON_MAX_LEN_UNLIMITED) { - max_scope_len = BSON_MAX (0, state->max_len - state->str->len); + BSON_ASSERT (bson_in_range_unsigned (int32_t, state->str->len)); + max_scope_len = BSON_MAX (0, state->max_len - (int32_t) state->str->len); } - scope = _bson_as_json_visit_all (v_scope, NULL, state->mode, max_scope_len); + scope = _bson_as_json_visit_all ( + v_scope, NULL, state->mode, max_scope_len, false); if (!scope) { return true; @@ -3165,7 +3168,9 @@ _bson_as_json_visit_document (const bson_iter_t *iter, child_state.mode = state->mode; child_state.max_len = BSON_MAX_LEN_UNLIMITED; if (state->max_len != BSON_MAX_LEN_UNLIMITED) { - child_state.max_len = BSON_MAX (0, state->max_len - state->str->len); + BSON_ASSERT (bson_in_range_unsigned (int32_t, state->str->len)); + child_state.max_len = + BSON_MAX (0, state->max_len - (int32_t) state->str->len); } child_state.max_len_reached = child_state.max_len == 0; @@ -3216,7 +3221,9 @@ _bson_as_json_visit_array (const bson_iter_t *iter, child_state.mode = state->mode; child_state.max_len = BSON_MAX_LEN_UNLIMITED; if (state->max_len != BSON_MAX_LEN_UNLIMITED) { - child_state.max_len = BSON_MAX (0, state->max_len - state->str->len); + BSON_ASSERT (bson_in_range_unsigned (int32_t, state->str->len)); + child_state.max_len = + BSON_MAX (0, state->max_len - (int32_t) state->str->len); } child_state.max_len_reached = child_state.max_len == 0; @@ -3247,7 +3254,8 @@ static char * _bson_as_json_visit_all (const bson_t *bson, size_t *length, bson_json_mode_t mode, - int32_t max_len) + int32_t max_len, + bool is_outermost_array) { bson_json_state_t state; bson_iter_t iter; @@ -3265,7 +3273,7 @@ _bson_as_json_visit_all (const bson_t *bson, *length = 3; } - return bson_strdup ("{ }"); + return bson_strdup (is_outermost_array ? "[ ]" : "{ }"); } if (!bson_iter_init (&iter, bson)) { @@ -3273,8 +3281,8 @@ _bson_as_json_visit_all (const bson_t *bson, } state.count = 0; - state.keys = true; - state.str = bson_string_new ("{ "); + state.keys = !is_outermost_array; + state.str = bson_string_new (is_outermost_array ? "[ " : "{ "); state.depth = 0; state.err_offset = &err_offset; state.mode = mode; @@ -3298,7 +3306,7 @@ _bson_as_json_visit_all (const bson_t *bson, */ remaining = state.max_len - state.str->len; if (state.max_len == BSON_MAX_LEN_UNLIMITED || remaining > 1) { - bson_string_append (state.str, " }"); + bson_string_append (state.str, is_outermost_array ? " ]" : " }"); } else if (remaining == 1) { bson_string_append (state.str, " "); } @@ -3316,15 +3324,16 @@ bson_as_json_with_opts (const bson_t *bson, size_t *length, const bson_json_opts_t *opts) { - return _bson_as_json_visit_all (bson, length, opts->mode, opts->max_len); + return _bson_as_json_visit_all ( + bson, length, opts->mode, opts->max_len, opts->is_outermost_array); } char * bson_as_canonical_extended_json (const bson_t *bson, size_t *length) { - const bson_json_opts_t opts = {BSON_JSON_MODE_CANONICAL, - BSON_MAX_LEN_UNLIMITED}; + const bson_json_opts_t opts = { + BSON_JSON_MODE_CANONICAL, BSON_MAX_LEN_UNLIMITED, false}; return bson_as_json_with_opts (bson, length, &opts); } @@ -3332,8 +3341,8 @@ bson_as_canonical_extended_json (const bson_t *bson, size_t *length) char * bson_as_json (const bson_t *bson, size_t *length) { - const bson_json_opts_t opts = {BSON_JSON_MODE_LEGACY, - BSON_MAX_LEN_UNLIMITED}; + const bson_json_opts_t opts = { + BSON_JSON_MODE_LEGACY, BSON_MAX_LEN_UNLIMITED, false}; return bson_as_json_with_opts (bson, length, &opts); } @@ -3341,8 +3350,8 @@ bson_as_json (const bson_t *bson, size_t *length) char * bson_as_relaxed_extended_json (const bson_t *bson, size_t *length) { - const bson_json_opts_t opts = {BSON_JSON_MODE_RELAXED, - BSON_MAX_LEN_UNLIMITED}; + const bson_json_opts_t opts = { + BSON_JSON_MODE_RELAXED, BSON_MAX_LEN_UNLIMITED, false}; return bson_as_json_with_opts (bson, length, &opts); } @@ -3350,57 +3359,27 @@ bson_as_relaxed_extended_json (const bson_t *bson, size_t *length) char * bson_array_as_json (const bson_t *bson, size_t *length) { - bson_json_state_t state; - bson_iter_t iter; - ssize_t err_offset = -1; - - BSON_ASSERT (bson); - - if (length) { - *length = 0; - } - - if (bson_empty0 (bson)) { - if (length) { - *length = 3; - } - - return bson_strdup ("[ ]"); - } - - if (!bson_iter_init (&iter, bson)) { - return NULL; - } - - state.count = 0; - state.keys = false; - state.str = bson_string_new ("[ "); - state.depth = 0; - state.err_offset = &err_offset; - state.mode = BSON_JSON_MODE_LEGACY; - state.max_len = BSON_MAX_LEN_UNLIMITED; - state.max_len_reached = false; + const bson_json_opts_t opts = { + BSON_JSON_MODE_LEGACY, BSON_MAX_LEN_UNLIMITED, true}; + return bson_as_json_with_opts (bson, length, &opts); +} - if ((bson_iter_visit_all (&iter, &bson_as_json_visitors, &state) || - err_offset != -1) && - !state.max_len_reached) { - /* - * We were prematurely exited due to corruption or failed visitor. - */ - bson_string_free (state.str, true); - if (length) { - *length = 0; - } - return NULL; - } - bson_string_append (state.str, " ]"); +char * +bson_array_as_relaxed_extended_json (const bson_t *bson, size_t *length) +{ + const bson_json_opts_t opts = { + BSON_JSON_MODE_RELAXED, BSON_MAX_LEN_UNLIMITED, true}; + return bson_as_json_with_opts (bson, length, &opts); +} - if (length) { - *length = state.str->len; - } - return bson_string_free (state.str, false); +char * +bson_array_as_canonical_extended_json (const bson_t *bson, size_t *length) +{ + const bson_json_opts_t opts = { + BSON_JSON_MODE_CANONICAL, BSON_MAX_LEN_UNLIMITED, true}; + return bson_as_json_with_opts (bson, length, &opts); } @@ -3669,3 +3648,345 @@ bson_concat (bson_t *dst, const bson_t *src) return true; } + +struct _bson_array_builder_t { + uint32_t index; + bson_t bson; +}; + +bson_array_builder_t * +bson_array_builder_new (void) +{ + bson_array_builder_t *bab = BSON_ALIGNED_ALLOC0 (bson_array_builder_t); + bson_init (&bab->bson); + return bab; +} + +// `bson_array_builder_append_impl` generates the next key index, calls +// `append_fn`, and may update the tracked next index. +#define bson_array_builder_append_impl(append_fn, ...) \ + if (1) { \ + BSON_ASSERT_PARAM (bab); \ + const char *key; \ + char buf[16]; \ + size_t key_length = \ + bson_uint32_to_string (bab->index, &key, buf, sizeof buf); \ + /* Expect enough room in `buf` for key string. UINT32_MAX is 10 digits. \ + * With the NULL terminator, 11 is expected maximum number of \ + * characters. */ \ + BSON_ASSERT (key_length < sizeof buf); \ + bool ok = append_fn (&bab->bson, key, (int) key_length, __VA_ARGS__); \ + if (ok) { \ + bab->index += 1; \ + } \ + return ok; \ + } else \ + (void) 0 + +#define bson_array_builder_append_impl_noargs(append_fn) \ + if (1) { \ + BSON_ASSERT_PARAM (bab); \ + const char *key; \ + char buf[16]; \ + size_t key_length = \ + bson_uint32_to_string (bab->index, &key, buf, sizeof buf); \ + /* Expect enough room in `buf` for key string. UINT32_MAX is 10 digits. \ + * With the NULL terminator, 11 is expected maximum number of \ + * characters. */ \ + BSON_ASSERT (key_length < sizeof buf); \ + bool ok = append_fn (&bab->bson, key, (int) key_length); \ + if (ok) { \ + bab->index += 1; \ + } \ + return ok; \ + } else \ + (void) 0 + +bool +bson_array_builder_append_value (bson_array_builder_t *bab, + const bson_value_t *value) +{ + bson_array_builder_append_impl (bson_append_value, value); +} + +bool +bson_array_builder_append_array (bson_array_builder_t *bab, const bson_t *array) +{ + bson_array_builder_append_impl (bson_append_array, array); +} + + +bool +bson_array_builder_append_binary (bson_array_builder_t *bab, + bson_subtype_t subtype, + const uint8_t *binary, + uint32_t length) +{ + bson_array_builder_append_impl (bson_append_binary, subtype, binary, length); +} + + +bool +bson_array_builder_append_bool (bson_array_builder_t *bab, bool value) +{ + bson_array_builder_append_impl (bson_append_bool, value); +} + + +bool +bson_array_builder_append_code (bson_array_builder_t *bab, + const char *javascript) +{ + bson_array_builder_append_impl (bson_append_code, javascript); +} + + +bool +bson_array_builder_append_code_with_scope (bson_array_builder_t *bab, + const char *javascript, + const bson_t *scope) +{ + bson_array_builder_append_impl ( + bson_append_code_with_scope, javascript, scope); +} + + +bool +bson_array_builder_append_dbpointer (bson_array_builder_t *bab, + const char *collection, + const bson_oid_t *oid) +{ + bson_array_builder_append_impl (bson_append_dbpointer, collection, oid); +} + + +bool +bson_array_builder_append_double (bson_array_builder_t *bab, double value) +{ + bson_array_builder_append_impl (bson_append_double, value); +} + + +bool +bson_array_builder_append_document (bson_array_builder_t *bab, + const bson_t *value) +{ + bson_array_builder_append_impl (bson_append_document, value); +} + + +bool +bson_array_builder_append_document_begin (bson_array_builder_t *bab, + bson_t *child) +{ + bson_array_builder_append_impl (bson_append_document_begin, child); +} + + +bool +bson_array_builder_append_document_end (bson_array_builder_t *bab, + bson_t *child) +{ + return bson_append_document_end (&bab->bson, child); +} + + +bool +bson_array_builder_append_int32 (bson_array_builder_t *bab, int32_t value) +{ + bson_array_builder_append_impl (bson_append_int32, value); +} + + +bool +bson_array_builder_append_int64 (bson_array_builder_t *bab, int64_t value) +{ + bson_array_builder_append_impl (bson_append_int64, value); +} + + +bool +bson_array_builder_append_decimal128 (bson_array_builder_t *bab, + const bson_decimal128_t *value) +{ + bson_array_builder_append_impl (bson_append_decimal128, value); +} + + +bool +bson_array_builder_append_iter (bson_array_builder_t *bab, + const bson_iter_t *iter) +{ + bson_array_builder_append_impl (bson_append_iter, iter); +} + + +bool +bson_array_builder_append_minkey (bson_array_builder_t *bab) +{ + bson_array_builder_append_impl_noargs (bson_append_minkey); +} + + +bool +bson_array_builder_append_maxkey (bson_array_builder_t *bab) +{ + bson_array_builder_append_impl_noargs (bson_append_maxkey); +} + + +bool +bson_array_builder_append_null (bson_array_builder_t *bab) +{ + bson_array_builder_append_impl_noargs (bson_append_null); +} + + +bool +bson_array_builder_append_oid (bson_array_builder_t *bab, const bson_oid_t *oid) +{ + bson_array_builder_append_impl (bson_append_oid, oid); +} + + +bool +bson_array_builder_append_regex (bson_array_builder_t *bab, + const char *regex, + const char *options) +{ + bson_array_builder_append_impl (bson_append_regex, regex, options); +} + + +bool +bson_array_builder_append_regex_w_len (bson_array_builder_t *bab, + const char *regex, + int regex_length, + const char *options) +{ + bson_array_builder_append_impl ( + bson_append_regex_w_len, regex, regex_length, options); +} + + +bool +bson_array_builder_append_utf8 (bson_array_builder_t *bab, + const char *value, + int length) +{ + bson_array_builder_append_impl (bson_append_utf8, value, length); +} + + +bool +bson_array_builder_append_symbol (bson_array_builder_t *bab, + const char *value, + int length) +{ + bson_array_builder_append_impl (bson_append_symbol, value, length); +} + + +bool +bson_array_builder_append_time_t (bson_array_builder_t *bab, time_t value) +{ + bson_array_builder_append_impl (bson_append_time_t, value); +} + + +bool +bson_array_builder_append_timeval (bson_array_builder_t *bab, + struct timeval *value) +{ + bson_array_builder_append_impl (bson_append_timeval, value); +} + + +bool +bson_array_builder_append_date_time (bson_array_builder_t *bab, int64_t value) +{ + bson_array_builder_append_impl (bson_append_date_time, value); +} + + +bool +bson_array_builder_append_now_utc (bson_array_builder_t *bab) +{ + bson_array_builder_append_impl_noargs (bson_append_now_utc); +} + + +bool +bson_array_builder_append_timestamp (bson_array_builder_t *bab, + uint32_t timestamp, + uint32_t increment) +{ + bson_array_builder_append_impl (bson_append_timestamp, timestamp, increment); +} + + +bool +bson_array_builder_append_undefined (bson_array_builder_t *bab) +{ + bson_array_builder_append_impl_noargs (bson_append_undefined); +} + + +bool +bson_array_builder_append_array_builder_begin (bson_array_builder_t *bab, + bson_array_builder_t **child) +{ + bson_array_builder_append_impl (bson_append_array_builder_begin, child); +} + +bool +bson_array_builder_append_array_builder_end (bson_array_builder_t *bab, + bson_array_builder_t *child) +{ + return bson_append_array_builder_end (&bab->bson, child); +} + + +bool +bson_array_builder_build (bson_array_builder_t *bab, bson_t *out) +{ + BSON_ASSERT_PARAM (bab); + BSON_ASSERT_PARAM (out); + if (!bson_steal (out, &bab->bson)) { + return false; + } + bson_init (&bab->bson); + bab->index = 0; + return true; +} + +void +bson_array_builder_destroy (bson_array_builder_t *bab) +{ + if (!bab) { + return; + } + bson_destroy (&bab->bson); + bson_free (bab); +} + +bool +bson_append_array_builder_begin (bson_t *bson, + const char *key, + int key_length, + bson_array_builder_t **child) +{ + BSON_ASSERT_PARAM (bson); + BSON_ASSERT_PARAM (key); + BSON_ASSERT_PARAM (child); + *child = bson_array_builder_new (); + return bson_append_array_begin (bson, key, key_length, &(*child)->bson); +} + +bool +bson_append_array_builder_end (bson_t *bson, bson_array_builder_t *child) +{ + bool ok = bson_append_array_end (bson, &child->bson); + bson_array_builder_destroy (child); + return ok; +} diff --git a/src/bson/bson.h b/src/bson/bson.h index 8ffc58ec..88a2f706 100644 --- a/src/bson/bson.h +++ b/src/bson/bson.h @@ -20,34 +20,34 @@ #define BSON_INSIDE -#include "bson-compat.h" +#include #include #include -#include "bson-macros.h" -#include "bson-config.h" -#include "bson-atomic.h" -#include "bson-cmp.h" -#include "bson-context.h" -#include "bson-clock.h" -#include "bson-decimal128.h" -#include "bson-error.h" -#include "bson-iter.h" -#include "bson-json.h" -#include "bson-keys.h" -#include "bson-md5.h" -#include "bson-memory.h" -#include "bson-oid.h" -#include "bson-reader.h" -#include "bson-string.h" -#include "bson-types.h" -#include "bson-utf8.h" -#include "bson-value.h" -#include "bson-version.h" -#include "bson-version-functions.h" -#include "bson-writer.h" -#include "bcon.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #undef BSON_INSIDE @@ -361,6 +361,7 @@ bson_copy_to_excluding_noinit_va (const bson_t *src, const char *first_exclude, va_list args); + /** * bson_destroy: * @bson: A bson_t. @@ -507,7 +508,7 @@ bson_validate_with_error (const bson_t *bson, * The caller is responsible for freeing the resulting string. If @length is * non-NULL, then the length of the resulting string will be placed in @length. * - * See http://docs.mongodb.org/manual/reference/mongodb-extended-json/ for + * See https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/ for * more information on extended JSON. * * Returns: A newly allocated string that should be freed with bson_free(). @@ -531,7 +532,7 @@ bson_as_json_with_opts (const bson_t *bson, * The caller is responsible for freeing the resulting string. If @length is * non-NULL, then the length of the resulting string will be placed in @length. * - * See http://docs.mongodb.org/manual/reference/mongodb-extended-json/ for + * See https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/ for * more information on extended JSON. * * Returns: A newly allocated string that should be freed with bson_free(). @@ -570,7 +571,7 @@ bson_as_json (const bson_t *bson, size_t *length); * The caller is responsible for freeing the resulting string. If @length is * non-NULL, then the length of the resulting string will be placed in @length. * - * See http://docs.mongodb.org/manual/reference/mongodb-extended-json/ for + * See https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/ for * more information on extended JSON. * * Returns: A newly allocated string that should be freed with bson_free(). @@ -580,16 +581,48 @@ bson_as_relaxed_extended_json (const bson_t *bson, size_t *length); /* like bson_as_json() but for outermost arrays. */ +BSON_EXPORT (char *) bson_array_as_json (const bson_t *bson, size_t *length); + + +/* like bson_as_relaxed_extended_json() but for outermost arrays. */ BSON_EXPORT (char *) -bson_array_as_json (const bson_t *bson, size_t *length); +bson_array_as_relaxed_extended_json (const bson_t *bson, size_t *length); +/* like bson_as_canonical_extended_json() but for outermost arrays. */ +BSON_EXPORT (char *) +bson_array_as_canonical_extended_json (const bson_t *bson, size_t *length); + +// bson_array_builder_t defines an API for building arrays. +// BSON arrays require sequential numeric keys "0", "1", "2", ... +typedef struct _bson_array_builder_t bson_array_builder_t; + +// bson_array_builder_new may be used to build a top-level BSON array. Example: +// `[1,2,3]`. +// To append an array field to a document (Example: `{ "field": [1,2,3] }`), use +// `bson_append_array_builder_begin`. +BSON_EXPORT (bson_array_builder_t *) bson_array_builder_new (void); + +// bson_array_builder_build initializes and moves BSON data to `out`. +// `bab` may be reused and will start appending a new array at index "0". +BSON_EXPORT (bool) +bson_array_builder_build (bson_array_builder_t *bab, bson_t *out); + +BSON_EXPORT (void) +bson_array_builder_destroy (bson_array_builder_t *bab); + BSON_EXPORT (bool) bson_append_value (bson_t *bson, const char *key, int key_length, const bson_value_t *value); +#define BSON_APPEND_VALUE(b, key, val) \ + bson_append_value (b, key, (int) strlen (key), (val)) + +BSON_EXPORT (bool) +bson_array_builder_append_value (bson_array_builder_t *bab, + const bson_value_t *value); /** * bson_append_array: @@ -609,6 +642,12 @@ bson_append_array (bson_t *bson, int key_length, const bson_t *array); +#define BSON_APPEND_ARRAY(b, key, val) \ + bson_append_array (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_array (bson_array_builder_t *bab, + const bson_t *array); /** * bson_append_binary: @@ -630,6 +669,14 @@ bson_append_binary (bson_t *bson, const uint8_t *binary, uint32_t length); +#define BSON_APPEND_BINARY(b, key, subtype, val, len) \ + bson_append_binary (b, key, (int) strlen (key), subtype, val, len) + +BSON_EXPORT (bool) +bson_array_builder_append_binary (bson_array_builder_t *bab, + bson_subtype_t subtype, + const uint8_t *binary, + uint32_t length); /** * bson_append_bool: @@ -644,6 +691,11 @@ bson_append_binary (bson_t *bson, BSON_EXPORT (bool) bson_append_bool (bson_t *bson, const char *key, int key_length, bool value); +#define BSON_APPEND_BOOL(b, key, val) \ + bson_append_bool (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_bool (bson_array_builder_t *bab, bool value); /** * bson_append_code: @@ -662,6 +714,12 @@ bson_append_code (bson_t *bson, int key_length, const char *javascript); +#define BSON_APPEND_CODE(b, key, val) \ + bson_append_code (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_code (bson_array_builder_t *bab, + const char *javascript); /** * bson_append_code_with_scope: @@ -682,6 +740,13 @@ bson_append_code_with_scope (bson_t *bson, const char *javascript, const bson_t *scope); +#define BSON_APPEND_CODE_WITH_SCOPE(b, key, val, scope) \ + bson_append_code_with_scope (b, key, (int) strlen (key), val, scope) + +BSON_EXPORT (bool) +bson_array_builder_append_code_with_scope (bson_array_builder_t *bab, + const char *javascript, + const bson_t *scope); /** * bson_append_dbpointer: @@ -702,6 +767,13 @@ bson_append_dbpointer (bson_t *bson, const char *collection, const bson_oid_t *oid); +#define BSON_APPEND_DBPOINTER(b, key, coll, oid) \ + bson_append_dbpointer (b, key, (int) strlen (key), coll, oid) + +BSON_EXPORT (bool) +bson_array_builder_append_dbpointer (bson_array_builder_t *bab, + const char *collection, + const bson_oid_t *oid); /** * bson_append_double: @@ -718,6 +790,11 @@ bson_append_double (bson_t *bson, int key_length, double value); +#define BSON_APPEND_DOUBLE(b, key, val) \ + bson_append_double (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_double (bson_array_builder_t *bab, double value); /** * bson_append_document: @@ -736,6 +813,12 @@ bson_append_document (bson_t *bson, int key_length, const bson_t *value); +#define BSON_APPEND_DOCUMENT(b, key, val) \ + bson_append_document (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_document (bson_array_builder_t *bab, + const bson_t *value); /** * bson_append_document_begin: @@ -760,6 +843,12 @@ bson_append_document_begin (bson_t *bson, int key_length, bson_t *child); +#define BSON_APPEND_DOCUMENT_BEGIN(b, key, child) \ + bson_append_document_begin (b, key, (int) strlen (key), child) + +BSON_EXPORT (bool) +bson_array_builder_append_document_begin (bson_array_builder_t *bab, + bson_t *child); /** * bson_append_document_end: @@ -774,6 +863,10 @@ bson_append_document_begin (bson_t *bson, BSON_EXPORT (bool) bson_append_document_end (bson_t *bson, bson_t *child); +BSON_EXPORT (bool) +bson_array_builder_append_document_end (bson_array_builder_t *bab, + bson_t *child); + /** * bson_append_array_begin: @@ -801,6 +894,8 @@ bson_append_array_begin (bson_t *bson, int key_length, bson_t *child); +#define BSON_APPEND_ARRAY_BEGIN(b, key, child) \ + bson_append_array_begin (b, key, (int) strlen (key), child) /** * bson_append_array_end: @@ -832,6 +927,11 @@ bson_append_int32 (bson_t *bson, int key_length, int32_t value); +#define BSON_APPEND_INT32(b, key, val) \ + bson_append_int32 (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_int32 (bson_array_builder_t *bab, int32_t value); /** * bson_append_int64: @@ -849,6 +949,11 @@ bson_append_int64 (bson_t *bson, int key_length, int64_t value); +#define BSON_APPEND_INT64(b, key, val) \ + bson_append_int64 (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_int64 (bson_array_builder_t *bab, int64_t value); /** * bson_append_decimal128: @@ -866,6 +971,12 @@ bson_append_decimal128 (bson_t *bson, int key_length, const bson_decimal128_t *value); +#define BSON_APPEND_DECIMAL128(b, key, val) \ + bson_append_decimal128 (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_decimal128 (bson_array_builder_t *bab, + const bson_decimal128_t *value); /** * bson_append_iter: @@ -885,6 +996,12 @@ bson_append_iter (bson_t *bson, int key_length, const bson_iter_t *iter); +#define BSON_APPEND_ITER(b, key, val) \ + bson_append_iter (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_iter (bson_array_builder_t *bab, + const bson_iter_t *iter); /** * bson_append_minkey: @@ -901,6 +1018,11 @@ bson_append_iter (bson_t *bson, BSON_EXPORT (bool) bson_append_minkey (bson_t *bson, const char *key, int key_length); +#define BSON_APPEND_MINKEY(b, key) \ + bson_append_minkey (b, key, (int) strlen (key)) + +BSON_EXPORT (bool) +bson_array_builder_append_minkey (bson_array_builder_t *bab); /** * bson_append_maxkey: @@ -917,6 +1039,11 @@ bson_append_minkey (bson_t *bson, const char *key, int key_length); BSON_EXPORT (bool) bson_append_maxkey (bson_t *bson, const char *key, int key_length); +#define BSON_APPEND_MAXKEY(b, key) \ + bson_append_maxkey (b, key, (int) strlen (key)) + +BSON_EXPORT (bool) +bson_array_builder_append_maxkey (bson_array_builder_t *bab); /** * bson_append_null: @@ -930,6 +1057,10 @@ bson_append_maxkey (bson_t *bson, const char *key, int key_length); BSON_EXPORT (bool) bson_append_null (bson_t *bson, const char *key, int key_length); +#define BSON_APPEND_NULL(b, key) bson_append_null (b, key, (int) strlen (key)) + +BSON_EXPORT (bool) +bson_array_builder_append_null (bson_array_builder_t *bab); /** * bson_append_oid: @@ -948,6 +1079,12 @@ bson_append_oid (bson_t *bson, int key_length, const bson_oid_t *oid); +#define BSON_APPEND_OID(b, key, val) \ + bson_append_oid (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_oid (bson_array_builder_t *bab, + const bson_oid_t *oid); /** * bson_append_regex: @@ -979,6 +1116,13 @@ bson_append_regex (bson_t *bson, const char *regex, const char *options); +#define BSON_APPEND_REGEX(b, key, val, opt) \ + bson_append_regex (b, key, (int) strlen (key), val, opt) + +BSON_EXPORT (bool) +bson_array_builder_append_regex (bson_array_builder_t *bab, + const char *regex, + const char *options); /** * bson_append_regex: @@ -1013,6 +1157,11 @@ bson_append_regex_w_len (bson_t *bson, int regex_length, const char *options); +BSON_EXPORT (bool) +bson_array_builder_append_regex_w_len (bson_array_builder_t *bab, + const char *regex, + int regex_length, + const char *options); /** * bson_append_utf8: @@ -1036,6 +1185,13 @@ bson_append_utf8 (bson_t *bson, const char *value, int length); +#define BSON_APPEND_UTF8(b, key, val) \ + bson_append_utf8 (b, key, (int) strlen (key), val, (int) strlen (val)) + +BSON_EXPORT (bool) +bson_array_builder_append_utf8 (bson_array_builder_t *bab, + const char *value, + int length); /** * bson_append_symbol: @@ -1058,6 +1214,13 @@ bson_append_symbol (bson_t *bson, const char *value, int length); +#define BSON_APPEND_SYMBOL(b, key, val) \ + bson_append_symbol (b, key, (int) strlen (key), val, (int) strlen (val)) + +BSON_EXPORT (bool) +bson_array_builder_append_symbol (bson_array_builder_t *bab, + const char *value, + int length); /** * bson_append_time_t: @@ -1076,6 +1239,11 @@ bson_append_time_t (bson_t *bson, int key_length, time_t value); +#define BSON_APPEND_TIME_T(b, key, val) \ + bson_append_time_t (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_time_t (bson_array_builder_t *bab, time_t value); /** * bson_append_timeval: @@ -1094,6 +1262,12 @@ bson_append_timeval (bson_t *bson, int key_length, struct timeval *value); +#define BSON_APPEND_TIMEVAL(b, key, val) \ + bson_append_timeval (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_timeval (bson_array_builder_t *bab, + struct timeval *value); /** * bson_append_date_time: @@ -1112,6 +1286,11 @@ bson_append_date_time (bson_t *bson, int key_length, int64_t value); +#define BSON_APPEND_DATE_TIME(b, key, val) \ + bson_append_date_time (b, key, (int) strlen (key), val) + +BSON_EXPORT (bool) +bson_array_builder_append_date_time (bson_array_builder_t *bab, int64_t value); /** * bson_append_now_utc: @@ -1127,6 +1306,12 @@ bson_append_date_time (bson_t *bson, BSON_EXPORT (bool) bson_append_now_utc (bson_t *bson, const char *key, int key_length); +#define BSON_APPEND_NOW_UTC(b, key) \ + bson_append_now_utc (b, key, (int) strlen (key)) + +BSON_EXPORT (bool) +bson_array_builder_append_now_utc (bson_array_builder_t *bab); + /** * bson_append_timestamp: * @bson: A bson_t. @@ -1150,6 +1335,13 @@ bson_append_timestamp (bson_t *bson, uint32_t timestamp, uint32_t increment); +#define BSON_APPEND_TIMESTAMP(b, key, val, inc) \ + bson_append_timestamp (b, key, (int) strlen (key), val, inc) + +BSON_EXPORT (bool) +bson_array_builder_append_timestamp (bson_array_builder_t *bab, + uint32_t timestamp, + uint32_t increment); /** * bson_append_undefined: @@ -1165,10 +1357,35 @@ bson_append_timestamp (bson_t *bson, BSON_EXPORT (bool) bson_append_undefined (bson_t *bson, const char *key, int key_length); +#define BSON_APPEND_UNDEFINED(b, key) \ + bson_append_undefined (b, key, (int) strlen (key)) + +BSON_EXPORT (bool) +bson_array_builder_append_undefined (bson_array_builder_t *bab); BSON_EXPORT (bool) bson_concat (bson_t *dst, const bson_t *src); +BSON_EXPORT (bool) +bson_append_array_builder_begin (bson_t *bson, + const char *key, + int key_length, + bson_array_builder_t **child); + +#define BSON_APPEND_ARRAY_BUILDER_BEGIN(b, key, child) \ + bson_append_array_builder_begin (b, key, (int) strlen (key), child) + +BSON_EXPORT (bool) +bson_array_builder_append_array_builder_begin (bson_array_builder_t *bab, + bson_array_builder_t **child); + +BSON_EXPORT (bool) +bson_append_array_builder_end (bson_t *bson, bson_array_builder_t *child); + +BSON_EXPORT (bool) +bson_array_builder_append_array_builder_end (bson_array_builder_t *bab, + bson_array_builder_t *child); + BSON_END_DECLS diff --git a/src/common/bson-dsl.h b/src/common/bson-dsl.h new file mode 100644 index 00000000..84d75700 --- /dev/null +++ b/src/common/bson-dsl.h @@ -0,0 +1,1386 @@ +#include "common-prelude.h" + +#ifndef BSON_BSON_DSL_H_INCLUDED +#define BSON_BSON_DSL_H_INCLUDED + +/** + * @file bson-dsl.h + * @brief Define a C-preprocessor DSL for working with BSON objects + * + * This file defines an embedded DSL for working with BSON objects consisely and + * correctly. + * + * For more information about using this DSL, refer to `bson-dsl.md`. + */ + +#include "bson/bson.h" + +enum { + /// Toggle this value to enable/disable debug output for all bsonDSL + /// operations (printed to stderr). You can also set a constant + /// BSON_DSL_DEBUG within the scope of a DSL command to selectively debug + /// only the commands within that scope. + BSON_DSL_DEBUG = 0 +}; + +#define _bson_thread_local \ + BSON_IF_GNU_LIKE (__thread) BSON_IF_MSVC (__declspec (thread)) + +#define _bson_comdat \ + BSON_IF_WINDOWS (__declspec (selectany)) \ + BSON_IF_POSIX (__attribute__ ((weak))) + +#ifdef __GNUC__ +// GCC has a bug handling pragma statements that disable warnings within complex +// nested macro expansions. If we're GCC, just disable -Wshadow outright: +BSON_IF_GNU_LIKE (_Pragma ("GCC diagnostic ignored \"-Wshadow\"")) +#endif + +#define _bsonDSL_disableWarnings() \ + if (1) { \ + BSON_IF_GNU_LIKE (_Pragma ("GCC diagnostic push");) \ + BSON_IF_GNU_LIKE (_Pragma ("GCC diagnostic ignored \"-Wshadow\"");) \ + } else \ + ((void) 0) + +#define _bsonDSL_restoreWarnings() \ + if (1) { \ + BSON_IF_GNU_LIKE (_Pragma ("GCC diagnostic pop");) \ + } else \ + ((void) 0) + +/** + * @brief Parse the given BSON document. + * + * @param doc A bson_t object to walk. (Not a pointer) + */ +#define bsonParse(Document, ...) \ + _bsonDSL_begin ("bsonParse(%s)", _bsonDSL_str (Document)); \ + _bsonDSL_disableWarnings (); \ + bsonParseError = NULL; \ + BSON_MAYBE_UNUSED bool _bvHalt = false; \ + BSON_MAYBE_UNUSED const bool _bvContinue = false; \ + BSON_MAYBE_UNUSED const bool _bvBreak = false; \ + _bsonDSL_eval (_bsonParse ((Document), __VA_ARGS__)); \ + _bsonDSL_restoreWarnings (); \ + _bsonDSL_end + +/** + * @brief Visit each element of a BSON document + */ +#define bsonVisitEach(Document, ...) \ + _bsonDSL_begin ("bsonVisitEach(%s)", _bsonDSL_str (Document)); \ + _bsonDSL_disableWarnings (); \ + BSON_MAYBE_UNUSED bool _bvHalt = false; \ + _bsonDSL_eval (_bsonVisitEach ((Document), __VA_ARGS__)); \ + _bsonDSL_restoreWarnings (); \ + _bsonDSL_end + +#define bsonBuildContext (*_bsonBuildContextThreadLocalPtr) +#define bsonVisitContext (*_bsonVisitContextThreadLocalPtr) +#define bsonVisitIter (bsonVisitContext.iter) + +/// Begin any function-like macro by opening a new scope and writing a debug +/// message. +#define _bsonDSL_begin(Str, ...) \ + if (true) { \ + _bsonDSLDebug (Str, __VA_ARGS__); \ + ++_bson_dsl_indent + +/// End a function-like macro scope. +#define _bsonDSL_end \ + --_bson_dsl_indent; \ + } \ + else ((void) 0) + +/** + * @brief Expands to a call to bson_append_{Kind}, with the three first + * arguments filled in by the DSL context variables. + */ +#define _bsonBuildAppendArgs \ + bsonBuildContext.doc, bsonBuildContext.key, bsonBuildContext.key_len + +/** + * The _bsonDocOperation_XYZ macros handle the top-level bsonBuild() + * items, and any nested doc() items, with XYZ being the doc-building + * subcommand. + */ +#define _bsonDocOperation(Command, _ignore, _count) \ + if (!bsonBuildError) { \ + _bsonDocOperation_##Command; \ + if (bsonBuildError) { \ + _bsonDSLDebug ("Stopping doc() due to bsonBuildError: [%s]", \ + bsonBuildError); \ + } \ + } + +#define _bsonValueOperation(P) _bsonValueOperation_##P + +/// key-value pair with explicit key length +#define _bsonDocOperation_kvl(String, Len, Element) \ + _bsonDSL_begin ("\"%s\" => [%s]", String, _bsonDSL_strElide (30, Element)); \ + const char *_bbString = (String); \ + const uint64_t length = (Len); \ + if (bson_in_range_unsigned (int, length)) { \ + _bbCtx.key = _bbString; \ + _bbCtx.key_len = (int) length; \ + _bsonValueOperation (Element); \ + } else { \ + bsonBuildError = "Out-of-range key string length value"; \ + } \ + _bsonDSL_end + +/// Key-value pair with a C-string +#define _bsonDocOperation_kv(String, Element) \ + _bsonDocOperation_kvl ((String), strlen ((String)), Element) + +/// Execute arbitrary code +#define _bsonDocOperation_do(...) \ + _bsonDSL_begin ("do(%s)", _bsonDSL_strElide (30, __VA_ARGS__)); \ + do { \ + __VA_ARGS__; \ + } while (0); \ + if (bsonBuildError) { \ + _bsonDSLDebug ("do() set bsonBuildError: [%s]", bsonBuildError); \ + } \ + _bsonDSL_end + +/// We must defer expansion of the nested doc() to allow "recursive" evaluation +#define _bsonValueOperation_doc \ + _bsonValueOperationDeferred_doc _bsonDSL_nothing () +#define _bsonArrayOperation_doc(...) _bsonArrayAppendValue (doc (__VA_ARGS__)) + +#define _bsonValueOperationDeferred_doc(...) \ + _bsonDSL_begin ("doc(%s)", _bsonDSL_strElide (30, __VA_ARGS__)); \ + /* Write to this variable as the child: */ \ + bson_t _bbChildDoc = BSON_INITIALIZER; \ + if (!bson_append_document_begin (_bsonBuildAppendArgs, &_bbChildDoc)) { \ + bsonBuildError = \ + "Error while initializing child document: " _bsonDSL_str ( \ + __VA_ARGS__); \ + } else { \ + _bsonBuildAppend (_bbChildDoc, __VA_ARGS__); \ + if (!bsonBuildError) { \ + if (!bson_append_document_end (bsonBuildContext.doc, &_bbChildDoc)) { \ + bsonBuildError = \ + "Error while finalizing document: " _bsonDSL_str (__VA_ARGS__); \ + } \ + } \ + } \ + _bsonDSL_end + +/// We must defer expansion of the nested array() to allow "recursive" +/// evaluation +#define _bsonValueOperation_array \ + _bsonValueOperationDeferred_array _bsonDSL_nothing () +#define _bsonArrayOperation_array(...) \ + _bsonArrayAppendValue (array (__VA_ARGS__)) + +#define _bsonValueOperationDeferred_array(...) \ + _bsonDSL_begin ("array(%s)", _bsonDSL_strElide (30, __VA_ARGS__)); \ + /* Write to this variable as the child array: */ \ + bson_t _bbArray = BSON_INITIALIZER; \ + if (!bson_append_array_begin (_bsonBuildAppendArgs, &_bbArray)) { \ + bsonBuildError = \ + "Error while initializing child array: " _bsonDSL_str (__VA_ARGS__); \ + } else { \ + _bsonBuildArray (_bbArray, __VA_ARGS__); \ + if (!bsonBuildError) { \ + if (!bson_append_array_end (bsonBuildContext.doc, &_bbArray)) { \ + bsonBuildError = \ + "Error while finalizing child array: " _bsonDSL_str ( \ + __VA_ARGS__); \ + } \ + } else { \ + _bsonDSLDebug ("Got bsonBuildError: [%s]", bsonBuildError); \ + } \ + } \ + _bsonDSL_end + +/// Append a UTF-8 string with an explicit length +#define _bsonValueOperation_utf8_w_len(String, Len) \ + if (!bson_append_utf8 (_bsonBuildAppendArgs, (String), (int) (Len))) { \ + bsonBuildError = \ + "Error while appending utf8 string: " _bsonDSL_str (String); \ + } else \ + ((void) 0) +#define _bsonArrayOperation_utf8_w_len(X) _bsonArrayAppendValue (utf8_w_len (X)) + +/// Append a "cstr" as UTF-8 +#define _bsonValueOperation_cstr(String) \ + _bsonValueOperation_utf8_w_len ((String), strlen (String)) +#define _bsonArrayOperation_cstr(X) _bsonArrayAppendValue (cstr (X)) + +/// Append an int32 +#define _bsonValueOperation_int32(Integer) \ + if (!bson_append_int32 (_bsonBuildAppendArgs, (Integer))) { \ + bsonBuildError = \ + "Error while appending int32(" _bsonDSL_str (Integer) ")"; \ + } else \ + ((void) 0) +#define _bsonArrayOperation_int32(X) _bsonArrayAppendValue (int32 (X)) + +/// Append an int64 +#define _bsonValueOperation_int64(Integer) \ + if (!bson_append_int64 (_bsonBuildAppendArgs, (Integer))) { \ + bsonBuildError = \ + "Error while appending int64(" _bsonDSL_str (Integer) ")"; \ + } else \ + ((void) 0) +#define _bsonArrayOperation_int64(X) _bsonArrayAppendValue (int64 (X)) + +/// Append the value referenced by a given iterator +#define _bsonValueOperation_iterValue(Iter) \ + if (!bson_append_iter (_bsonBuildAppendArgs, &(Iter))) { \ + bsonBuildError = \ + "Error while appending iterValue(" _bsonDSL_str (Iter) ")"; \ + } else \ + ((void) 0) +#define _bsonArrayOperation_iterValue(X) _bsonArrayAppendValue (iterValue (X)) + +/// Append the BSON document referenced by the given pointer +#define _bsonValueOperation_bson(Doc) \ + if (!bson_append_document (_bsonBuildAppendArgs, &(Doc))) { \ + bsonBuildError = \ + "Error while appending subdocument: bson(" _bsonDSL_str (Doc) ")"; \ + } else \ + ((void) 0) +#define _bsonArrayOperation_bson(X) _bsonArrayAppendValue (bson (X)) + +/// Append the BSON document referenced by the given pointer as an array +#define _bsonValueOperation_bsonArray(Arr) \ + if (!bson_append_array (_bsonBuildAppendArgs, &(Arr))) { \ + bsonBuildError = "Error while appending subdocument array: " \ + "bsonArray(" _bsonDSL_str (Arr) ")"; \ + } else \ + ((void) 0) +#define _bsonArrayOperation_bsonArray(X) _bsonArrayAppendValue (bsonArray (X)) + +#define _bsonValueOperation_bool(b) \ + if (!bson_append_bool (_bsonBuildAppendArgs, (b))) { \ + bsonBuildError = "Error while appending bool(" _bsonDSL_str (b) ")"; \ + } else \ + ((void) 0) +#define _bsonArrayOperation_bool(X) _bsonArrayAppendValue (bool (X)) +#define _bsonValueOperation__Bool(b) _bsonValueOperation_bool (b) +#define _bsonArrayOperation__Bool(X) _bsonArrayAppendValue (_Bool (X)) + +#define _bsonValueOperation_null \ + if (!bson_append_null (_bsonBuildAppendArgs)) { \ + bsonBuildError = "Error while appending a null"; \ + } else \ + ((void) 0) +#define _bsonArrayOperation_null _bsonValueOperation (null) + +#define _bsonArrayOperation_value(X) _bsonArrayAppendValue (value (X)) + +#define _bsonValueOperation_value(Value) \ + _bsonDSL_begin ("value(%s)", _bsonDSL_str (Value)); \ + if (!bson_append_value (_bsonBuildAppendArgs, &(Value))) { \ + bsonBuildError = \ + "Error while appending value(" _bsonDSL_str (Value) ")"; \ + } \ + _bsonDSL_end + +/// Insert the given BSON document into the parent document in-place +#define _bsonDocOperation_insert(OtherBSON, Pred) \ + _bsonDSL_begin ("Insert other document: [%s]", _bsonDSL_str (OtherBSON)); \ + const bool _bvHalt = false; /* Required for _bsonVisitEach() */ \ + _bsonVisitEach ( \ + OtherBSON, \ + if (Pred, then (do (_bsonDocOperation_iterElement (bsonVisitIter))))); \ + _bsonDSL_end + +#define _bsonDocOperation_insertFromIter(Iter, Pred) \ + _bsonDSL_begin ("Insert document from iterator: [%s]", \ + _bsonDSL_str (Iter)); \ + bson_t _bbDocFromIter = _bson_dsl_iter_as_doc (&(Iter)); \ + if (_bbDocFromIter.len == 0) { \ + _bsonDSLDebug ( \ + "NOTE: Skipping insert of non-document value from iterator"); \ + } else { \ + _bsonDocOperation_insert (_bbDocFromIter, Pred); \ + } \ + _bsonDSL_end + +#define _bsonDocOperation_iterElement(Iter) \ + _bsonDSL_begin ("Insert element from bson_iter_t [%s]", \ + _bsonDSL_str (Iter)); \ + bson_iter_t _bbIter = (Iter); \ + _bsonDocOperation_kvl (bson_iter_key (&_bbIter), \ + bson_iter_key_len (&_bbIter), \ + iterValue (_bbIter)); \ + _bsonDSL_end + +/// Insert the given BSON document into the parent array. Keys of the given +/// document are discarded and it is treated as an array of values. +#define _bsonArrayOperation_insert(OtherArr, Pred) \ + _bsonDSL_begin ("Insert other array: [%s]", _bsonDSL_str (OtherArr)); \ + _bsonVisitEach ( \ + OtherArr, \ + if (Pred, then (do (_bsonArrayOperation_iterValue (bsonVisitIter))))); \ + _bsonDSL_end + +#define _bsonArrayAppendValue(ValueOperation) \ + _bsonDSL_begin ("[%d] => [%s]", \ + (int) bsonBuildContext.index, \ + _bsonDSL_strElide (30, ValueOperation)); \ + /* Set the doc key to the array index as a string: */ \ + _bsonBuild_setKeyToArrayIndex (bsonBuildContext.index); \ + /* Append a value: */ \ + _bsonValueOperation_##ValueOperation; \ + /* Increment the array index: */ \ + ++_bbCtx.index; \ + _bsonDSL_end + + +#define _bsonDocOperationIfThen_then _bsonBuildAppendWithCurrentContext +#define _bsonDocOperationIfElse_else _bsonBuildAppendWithCurrentContext + +#define _bsonDocOperationIfThenElse(Condition, Then, Else) \ + if ((Condition)) { \ + _bsonDSLDebug ("Taking TRUE branch: [%s]", _bsonDSL_str (Then)); \ + _bsonDocOperationIfThen_##Then; \ + } else { \ + _bsonDSLDebug ("Taking FALSE branch: [%s]", _bsonDSL_str (Else)); \ + _bsonDocOperationIfElse_##Else; \ + } + +#define _bsonDocOperationIfThen(Condition, Then) \ + if ((Condition)) { \ + _bsonDSLDebug ("Taking TRUE branch: [%s]", _bsonDSL_str (Then)); \ + _bsonDocOperationIfThen_##Then; \ + } + +#define _bsonDocOperation_if(Condition, ...) \ + _bsonDSL_begin ("Conditional append on [%s]", _bsonDSL_str (Condition)); \ + /* Pick a sub-macro depending on if there are one or two args */ \ + _bsonDSL_ifElse (_bsonDSL_hasComma (__VA_ARGS__), \ + _bsonDocOperationIfThenElse, \ + _bsonDocOperationIfThen) (Condition, __VA_ARGS__); \ + _bsonDSL_end + +#define _bsonArrayOperationIfThen_then _bsonBuildArrayWithCurrentContext +#define _bsonArrayOperationIfElse_else _bsonBuildArrayWithCurrentContext + +#define _bsonArrayOperationIfThenElse(Condition, Then, Else) \ + if ((Condition)) { \ + _bsonDSLDebug ("Taking TRUE branch: [%s]", _bsonDSL_str (Then)); \ + _bsonArrayOperationIfThen_##Then; \ + } else { \ + _bsonDSLDebug ("Taking FALSE branch: [%s]", _bsonDSL_str (Else)); \ + _bsonArrayOperationIfElse_##Else; \ + } + +#define _bsonArrayOperationIfThen(Condition, Then) \ + if ((Condition)) { \ + _bsonDSLDebug ("Taking TRUE branch: [%s]", _bsonDSL_str (Then)); \ + _bsonArrayOperationIfThen_##Then; \ + } + +#define _bsonArrayOperation_if(Condition, ...) \ + _bsonDSL_begin ("Conditional value on [%s]", _bsonDSL_str (Condition)); \ + /* Pick a sub-macro depending on if there are one or two args */ \ + _bsonDSL_ifElse (_bsonDSL_hasComma (__VA_ARGS__), \ + _bsonArrayOperationIfThenElse, \ + _bsonArrayOperationIfThen) (Condition, __VA_ARGS__); \ + _bsonDSL_end + +#define _bsonValueOperationIf_then(X) _bsonValueOperation_##X +#define _bsonValueOperationIf_else(X) _bsonValueOperation_##X + +#define _bsonValueOperation_if(Condition, Then, Else) \ + if ((Condition)) { \ + _bsonDSLDebug ("Taking TRUE branch: [%s]", _bsonDSL_str (Then)); \ + _bsonValueOperationIf_##Then; \ + } else { \ + _bsonDSLDebug ("Taking FALSE branch: [%s]", _bsonDSL_str (Else)); \ + _bsonValueOperationIf_##Else; \ + } + +#define _bsonBuild_setKeyToArrayIndex(Idx) \ + _bbCtx.key_len = bson_snprintf (_bbCtx.index_key_str, \ + sizeof _bbCtx.index_key_str, \ + "%d", \ + (int) _bbCtx.index); \ + _bbCtx.key = _bbCtx.index_key_str + +/// Handle an element of array() +#define _bsonArrayOperation(Element, _nil, _count) \ + if (!bsonBuildError) { \ + _bsonArrayOperation_##Element; \ + } + +#define _bsonBuildAppendWithCurrentContext(...) \ + _bsonDSL_mapMacro (_bsonDocOperation, ~, __VA_ARGS__) + +#define _bsonBuildArrayWithCurrentContext(...) \ + _bsonDSL_mapMacro (_bsonArrayOperation, ~, __VA_ARGS__) + +#define _bsonDSL_Type_double BSON_TYPE_DOUBLE +#define _bsonDSL_Type_utf8 BSON_TYPE_UTF8 +#define _bsonDSL_Type_doc BSON_TYPE_DOCUMENT +#define _bsonDSL_Type_array BSON_TYPE_ARRAY +#define _bsonDSL_Type_binary BSON_TYPE_BINARY +#define _bsonDSL_Type_undefined BSON_TYPE_UNDEFINED +#define _bsonDSL_Type_oid BSON_TYPE_OID +#define _bsonDSL_Type_bool BSON_TYPE_BOOL +// ("bool" may be spelled _Bool due to macro expansion:) +#define _bsonDSL_Type__Bool BSON_TYPE_BOOL +#define _bsonDSL_Type_date_time BSON_TYPE_DATE_TIME +#define _bsonDSL_Type_null BSON_TYPE_NULL +#define _bsonDSL_Type_regex BSON_TYPE_REGEX +#define _bsonDSL_Type_dbpointer BSON_TYPE_DBPOINTER +#define _bsonDSL_Type_code BSON_TYPE_CODE +#define _bsonDSL_Type_codewscope BSON_TYPE_CODEWSCOPE +#define _bsonDSL_Type_int32 BSON_TYPE_INT32 +#define _bsonDSL_Type_timestamp BSON_TYPE_TIMESTAMP +#define _bsonDSL_Type_int64 BSON_TYPE_INT64 +#define _bsonDSL_Type_decimal128 BSON_TYPE_DECIMAL128 + +#define _bsonDSL_Type_string __NOTE__No_type_named__string__did_you_mean__utf8 + +#define _bsonVisitOperation_halt _bvHalt = true + +#define _bsonVisitOperation_if(Predicate, ...) \ + _bsonDSL_begin ("if(%s)", _bsonDSL_str (Predicate)); \ + _bsonDSL_ifElse (_bsonDSL_hasComma (__VA_ARGS__), \ + _bsonVisit_ifThenElse, \ + _bsonVisit_ifThen) (Predicate, __VA_ARGS__); \ + _bsonDSL_end + +#define _bsonVisit_ifThenElse(Predicate, Then, Else) \ + if (bsonPredicate (Predicate)) { \ + _bsonDSLDebug ("then:"); \ + _bsonVisit_ifThen_##Then; \ + } else { \ + _bsonDSLDebug ("else:"); \ + _bsonVisit_ifElse_##Else; \ + } + +#define _bsonVisit_ifThen(Predicate, Then) \ + if (bsonPredicate (Predicate)) { \ + _bsonDSLDebug ("then:"); \ + _bsonVisit_ifThen_##Then; \ + } else { \ + _bsonDSLDebug ("[else nothing]"); \ + } + +#define _bsonVisit_ifThen_then _bsonVisit_applyOps +#define _bsonVisit_ifElse_else _bsonVisit_applyOps + +#define _bsonVisitOperation_storeBool(Dest) \ + _bsonDSL_begin ("storeBool(%s)", _bsonDSL_str (Dest)); \ + (Dest) = bson_iter_as_bool (&bsonVisitIter); \ + _bsonDSL_end + +#define _bsonVisitOperation_storeStrRef(Dest) \ + _bsonDSL_begin ("storeStrRef(%s)", _bsonDSL_str (Dest)); \ + (Dest) = bson_iter_utf8 (&bsonVisitIter, NULL); \ + _bsonDSL_end + +#define _bsonVisitOperation_storeStrDup(Dest) \ + _bsonDSL_begin ("storeStrDup(%s)", _bsonDSL_str (Dest)); \ + (Dest) = bson_iter_dup_utf8 (&bsonVisitIter, NULL); \ + _bsonDSL_end + +#define _bsonVisitOperation_storeDocDup(Dest) \ + _bsonDSL_begin ("storeDocDup(%s)", _bsonDSL_str (Dest)); \ + bson_t _bvDoc = BSON_INITIALIZER; \ + _bson_dsl_iter_as_doc (&_bvDoc, &bsonVisitIter); \ + if (_bvDoc.len) { \ + bson_copy_to (&_bvDoc, &(Dest)); \ + } \ + _bsonDSL_end + +#define _bsonVisitOperation_storeDocRef(Dest) \ + _bsonDSL_begin ("storeDocRef(%s)", _bsonDSL_str (Dest)); \ + _bson_dsl_iter_as_doc (&(Dest), &bsonVisitIter); \ + _bsonDSL_end + +#define _bsonVisitOperation_storeDocDupPtr(Dest) \ + _bsonDSL_begin ("storeDocDupPtr(%s)", _bsonDSL_str (Dest)); \ + bson_t _bvDoc = BSON_INITIALIZER; \ + _bson_dsl_iter_as_doc (&_bvDoc, &bsonVisitIter); \ + if (_bvDoc.len) { \ + (Dest) = bson_copy (&_bvDoc); \ + } \ + _bsonDSL_end + +#define _bsonVisitOperation_storeInt32(Dest) \ + _bsonDSL_begin ("storeInt32(%s)", _bsonDSL_str (Dest)); \ + (Dest) = bson_iter_int32 (&bsonVisitIter); \ + _bsonDSL_end + +#define _bsonVisitOperation_do(...) \ + _bsonDSL_begin ("do: %s", _bsonDSL_strElide (30, __VA_ARGS__)); \ + do { \ + __VA_ARGS__; \ + } while (0); \ + _bsonDSL_end + +#define _bsonVisitOperation_appendTo(BSON) \ + _bsonDSL_begin ("appendTo(%s)", _bsonDSL_str (BSON)); \ + if (!bson_append_iter (&(BSON), \ + bson_iter_key (&bsonVisitIter), \ + (int) bson_iter_key_len (&bsonVisitIter), \ + &bsonVisitIter)) { \ + bsonParseError = "Error in appendTo(" _bsonDSL_str (BSON) ")"; \ + } \ + _bsonDSL_end + +#define _bsonVisitCase_when(Pred, ...) \ + _bsonDSL_begin ("when: [%s]", _bsonDSL_str (Pred)); \ + _bvCaseMatched = _bsonPredicate (Pred); \ + if (_bvCaseMatched) { \ + _bsonVisit_applyOps (__VA_ARGS__); \ + } \ + _bsonDSL_end + +#define _bsonVisitCase_else(...) \ + _bsonDSL_begin ("else:%s", ""); \ + _bvCaseMatched = true; \ + _bsonVisit_applyOps (__VA_ARGS__); \ + _bsonDSL_end + +#define _bsonVisitCase(Pair, _nil, _count) \ + if (!_bvCaseMatched) { \ + _bsonVisitCase_##Pair; \ + } else \ + ((void) 0); + +#define _bsonVisitOperation_case(...) \ + _bsonDSL_begin ("case:%s", ""); \ + BSON_MAYBE_UNUSED bool _bvCaseMatched = false; \ + _bsonDSL_mapMacro (_bsonVisitCase, ~, __VA_ARGS__); \ + _bsonDSL_end + +#define _bsonVisitOperation_append \ + _bsonVisitOneApplyDeferred_append _bsonDSL_nothing () +#define _bsonVisitOneApplyDeferred_append(Doc, ...) \ + _bsonDSL_begin ("append to [%s] : %s", \ + _bsonDSL_str (Doc), \ + _bsonDSL_strElide (30, __VA_ARGS__)); \ + _bsonBuildAppend (Doc, __VA_ARGS__); \ + if (bsonBuildError) { \ + bsonParseError = bsonBuildError; \ + } \ + _bsonDSL_end + +#define _bsonVisitEach(Doc, ...) \ + _bsonDSL_begin ("visitEach(%s)", _bsonDSL_str (Doc)); \ + do { \ + /* Reset the context */ \ + struct _bsonVisitContext_t _bvCtx = { \ + .doc = &(Doc), \ + .parent = _bsonVisitContextThreadLocalPtr, \ + .index = 0, \ + }; \ + _bsonVisitContextThreadLocalPtr = &_bvCtx; \ + bsonParseError = NULL; \ + /* Iterate over each element of the document */ \ + if (!bson_iter_init (&_bvCtx.iter, &(Doc))) { \ + bsonParseError = "Invalid BSON data [a]"; \ + } \ + BSON_MAYBE_UNUSED bool _bvBreak = false; \ + BSON_MAYBE_UNUSED bool _bvContinue = false; \ + while (bson_iter_next (&_bvCtx.iter) && !_bvHalt && !bsonParseError && \ + !_bvBreak) { \ + _bvContinue = false; \ + _bsonVisit_applyOps (__VA_ARGS__); \ + ++_bvCtx.index; \ + } \ + if (bsonVisitIter.err_off) { \ + bsonParseError = "Invalid BSON data [b]"; \ + } \ + /* Restore the dsl context */ \ + _bsonVisitContextThreadLocalPtr = _bvCtx.parent; \ + } while (0); \ + _bsonDSL_end + +#define _bsonVisitOperation_visitEach \ + _bsonVisitOperation_visitEachDeferred _bsonDSL_nothing () +#define _bsonVisitOperation_visitEachDeferred(...) \ + _bsonDSL_begin ("visitEach:%s", ""); \ + do { \ + const uint8_t *data; \ + uint32_t len; \ + bson_type_t typ = bson_iter_type_unsafe (&bsonVisitIter); \ + if (typ == BSON_TYPE_ARRAY) \ + bson_iter_array (&bsonVisitIter, &len, &data); \ + else if (typ == BSON_TYPE_DOCUMENT) \ + bson_iter_document (&bsonVisitIter, &len, &data); \ + else { \ + _bsonDSLDebug ("(Skipping visitEach() of non-array/document value)"); \ + break; \ + } \ + bson_t inner; \ + BSON_ASSERT (bson_init_static (&inner, data, len)); \ + _bsonVisitEach (inner, __VA_ARGS__); \ + } while (0); \ + _bsonDSL_end + +#define _bsonVisitOperation_nop _bsonDSLDebug ("[nop]") +#define _bsonVisitOperation_parse(...) \ + do { \ + const uint8_t *data; \ + uint32_t len; \ + bson_type_t typ = bson_iter_type (&bsonVisitIter); \ + if (typ == BSON_TYPE_ARRAY) \ + bson_iter_array (&bsonVisitIter, &len, &data); \ + else if (typ == BSON_TYPE_DOCUMENT) \ + bson_iter_document (&bsonVisitIter, &len, &data); \ + else { \ + _bsonDSLDebug ("Ignoring parse() for non-document/array value"); \ + break; \ + } \ + bson_t inner; \ + BSON_ASSERT (bson_init_static (&inner, data, len)); \ + _bsonParse (inner, __VA_ARGS__); \ + } while (0); + +#define _bsonVisitOperation_continue _bvContinue = true +#define _bsonVisitOperation_break _bvBreak = _bvContinue = true +#define _bsonVisitOperation_require(Predicate) \ + _bsonDSL_begin ("require(%s)", _bsonDSL_str (Predicate)); \ + if (!bsonPredicate (Predicate)) { \ + bsonParseError = \ + "Element requirement failed: " _bsonDSL_str (Predicate); \ + } \ + _bsonDSL_end + +#define _bsonVisitOperation_error(S) bsonParseError = (S) +#define _bsonVisitOperation_errorf(S, ...) \ + (bsonParseError = _bson_dsl_errorf (&(S), __VA_ARGS__)) +#define _bsonVisitOperation_dupPath(S) \ + _bsonDSL_begin ("dupPath(%s)", _bsonDSL_str (S)); \ + _bson_dsl_dupPath (&(S)); \ + _bsonDSL_end + +#define _bsonVisit_applyOp(P, _const, _count) \ + do { \ + if (!_bvContinue && !_bvHalt && !bsonParseError) { \ + _bsonVisitOperation_##P; \ + } \ + } while (0); + +#define _bsonParse(Doc, ...) \ + do { \ + BSON_MAYBE_UNUSED const bson_t *_bpDoc = &(Doc); \ + /* Keep track of which elements have been visited based on their index*/ \ + uint64_t _bpVisitBits_static[4] = {0}; \ + BSON_MAYBE_UNUSED uint64_t *_bpVisitBits = _bpVisitBits_static; \ + BSON_MAYBE_UNUSED size_t _bpNumVisitBitInts = \ + sizeof _bpVisitBits_static / sizeof (uint64_t); \ + BSON_MAYBE_UNUSED bool _bpFoundElement = false; \ + _bsonParse_applyOps (__VA_ARGS__); \ + /* We may have allocated for visit bits */ \ + if (_bpVisitBits != _bpVisitBits_static) { \ + bson_free (_bpVisitBits); \ + } \ + } while (0) + +#define _bsonParse_applyOps(...) \ + _bsonDSL_mapMacro (_bsonParse_applyOp, ~, __VA_ARGS__) + +/// Parse one entry referrenced by the context iterator +#define _bsonParse_applyOp(P, _nil, Counter) \ + do { \ + if (!_bvHalt && !bsonParseError) { \ + _bsonParseOperation_##P; \ + } \ + } while (0); + +#define _bsonParseMarkVisited(Index) \ + if (1) { \ + const size_t nth_int = Index / 64u; \ + const size_t nth_bit = Index % 64u; \ + while (nth_int >= _bpNumVisitBitInts) { \ + /* Say that five times, fast: */ \ + size_t new_num_visit_bit_ints = _bpNumVisitBitInts * 2u; \ + uint64_t *new_visit_bit_ints = \ + bson_malloc0 (sizeof (uint64_t) * new_num_visit_bit_ints); \ + memcpy (new_visit_bit_ints, \ + _bpVisitBits, \ + sizeof (uint64_t) * _bpNumVisitBitInts); \ + if (_bpVisitBits != _bpVisitBits_static) { \ + bson_free (_bpVisitBits); \ + } \ + _bpVisitBits = new_visit_bit_ints; \ + _bpNumVisitBitInts = new_num_visit_bit_ints; \ + } \ + \ + _bpVisitBits[nth_int] |= (UINT64_C (1) << nth_bit); \ + } else \ + ((void) 0) + +#define _bsonParseDidVisitNth(Index) \ + _bsonParseDidVisitNth_1 (Index / 64u, Index % 64u) +#define _bsonParseDidVisitNth_1(NthInt, NthBit) \ + (NthInt < _bpNumVisitBitInts && \ + (_bpVisitBits[NthInt] & (UINT64_C (1) << NthBit))) + +#define _bsonParseOperation_find(Predicate, ...) \ + _bsonDSL_begin ("find(%s)", _bsonDSL_str (Predicate)); \ + _bpFoundElement = false; \ + _bsonVisitEach ( \ + *_bpDoc, \ + if (Predicate, \ + then (do (_bsonParseMarkVisited (bsonVisitContext.index); \ + _bpFoundElement = true), \ + __VA_ARGS__, \ + break))); \ + if (!_bpFoundElement && !bsonParseError) { \ + _bsonDSLDebug ("[not found]"); \ + } \ + _bsonDSL_end + +#define _bsonParseOperation_require(Predicate, ...) \ + _bsonDSL_begin ("require(%s)", _bsonDSL_str (Predicate)); \ + _bpFoundElement = false; \ + _bsonVisitEach ( \ + *_bpDoc, \ + if (Predicate, \ + then (do (_bsonParseMarkVisited (bsonVisitContext.index); \ + _bpFoundElement = true), \ + __VA_ARGS__, \ + break))); \ + if (!_bpFoundElement && !bsonParseError) { \ + bsonParseError = \ + "Failed to find a required element: " _bsonDSL_str (Predicate); \ + } \ + _bsonDSL_end + +#define _bsonParseOperation_visitOthers(...) \ + _bsonDSL_begin ("visitOthers(%s)", _bsonDSL_strElide (30, __VA_ARGS__)); \ + _bsonVisitEach ( \ + *_bpDoc, \ + if (not(eval (_bsonParseDidVisitNth (bsonVisitContext.index))), \ + then (__VA_ARGS__))); \ + _bsonDSL_end + +#define bsonPredicate(P) _bsonPredicate _bsonDSL_nothing () (P) +#define _bsonPredicate(P) _bsonPredicate_Condition_##P + +#define _bsonPredicate_Condition_ \ + __NOTE__Missing_name_for_a_predicate_expression + +#define _bsonPredicate_Condition_allOf(...) \ + (1 _bsonDSL_mapMacro (_bsonPredicateAnd, ~, __VA_ARGS__)) +#define _bsonPredicate_Condition_anyOf(...) \ + (0 _bsonDSL_mapMacro (_bsonPredicateOr, ~, __VA_ARGS__)) +#define _bsonPredicate_Condition_not(...) \ + (!(0 _bsonDSL_mapMacro (_bsonPredicateOr, ~, __VA_ARGS__))) +#define _bsonPredicateAnd(Pred, _ignore, _ignore1) \ + &&_bsonPredicate _bsonDSL_nothing () (Pred) +#define _bsonPredicateOr(Pred, _ignore, _ignore2) \ + || _bsonPredicate _bsonDSL_nothing () (Pred) + +#define _bsonPredicate_Condition_eval(X) (X) + +#define _bsonPredicate_Condition_key(...) \ + (_bson_dsl_key_is_anyof (bson_iter_key (&bsonVisitIter), \ + bson_iter_key_len (&bsonVisitIter), \ + true /* case senstive */, \ + __VA_ARGS__, \ + NULL)) + +#define _bsonPredicate_Condition_iKey(...) \ + (_bson_dsl_key_is_anyof (bson_iter_key (&bsonVisitIter), \ + bson_iter_key_len (&bsonVisitIter), \ + false /* case insenstive */, \ + __VA_ARGS__, \ + NULL)) + +#define _bsonPredicate_Condition_type(Type) \ + (bson_iter_type (&bsonVisitIter) == _bsonDSL_Type_##Type) + +#define _bsonPredicate_Condition_keyWithType(Key, Type) \ + (_bsonPredicate_Condition_allOf _bsonDSL_nothing () (key (Key), type (Type))) + +#define _bsonPredicate_Condition_iKeyWithType(Key, Type) \ + (_bsonPredicate_Condition_allOf _bsonDSL_nothing () (iKey (Key), \ + type (Type))) + +#define _bsonPredicate_Condition_lastElement \ + (_bson_dsl_iter_is_last_element (&bsonVisitIter)) + +#define _bsonPredicate_Condition_isNumeric \ + BSON_ITER_HOLDS_NUMBER (&bsonVisitIter) + +#define _bsonPredicate_Condition_1 1 +#define _bsonPredicate_Condition_0 0 +#define _bsonPredicate_Condition_true true +#define _bsonPredicate_Condition_false false + +#define _bsonPredicate_Condition_isTrue (bson_iter_as_bool (&bsonVisitIter)) +#define _bsonPredicate_Condition_isFalse (!bson_iter_as_bool (&bsonVisitIter)) +#define _bsonPredicate_Condition_empty \ + (_bson_dsl_is_empty_bson (&bsonVisitIter)) + +#define _bsonPredicate_Condition_strEqual(S) (_bson_dsl_test_strequal (S, true)) +#define _bsonPredicate_Condition_iStrEqual(S) \ + (_bson_dsl_test_strequal (S, false)) + +#define _bsonPredicate_Condition_eq(Type, Value) \ + (_bsonPredicate_Condition_type (Type) && bsonAs (Type) == Value) + +#define _bsonParseOperation_else _bsonParse_deferredElse _bsonDSL_nothing () +#define _bsonParse_deferredElse(...) \ + if (!_bpFoundElement) { \ + _bsonDSL_begin ("else:%s", ""); \ + _bsonParse_applyOps (__VA_ARGS__); \ + _bsonDSL_end; \ + } else \ + ((void) 0) + +#define _bsonParseOperation_do(...) \ + _bsonDSL_begin ("do: %s", _bsonDSL_strElide (30, __VA_ARGS__)); \ + do { \ + __VA_ARGS__; \ + } while (0); \ + _bsonDSL_end + +#define _bsonParseOperation_halt _bvHalt = true + +#define _bsonParseOperation_error(S) bsonParseError = (S) +#define _bsonParseOperation_errorf(S, ...) \ + (bsonParseError = _bson_dsl_errorf (&(S), __VA_ARGS__)) + +/// Perform conditional parsing +#define _bsonParseOperation_if(Condition, ...) \ + _bsonDSL_begin ("if(%s)", _bsonDSL_str (Condition)); \ + /* Pick a sub-macro depending on if there are one or two args */ \ + _bsonDSL_ifElse (_bsonDSL_hasComma (__VA_ARGS__), \ + _bsonParse_ifThenElse, \ + _bsonParse_ifThen) (Condition, __VA_ARGS__); \ + _bsonDSL_end + +#define _bsonParse_ifThen_then _bsonParse_applyOps +#define _bsonParse_ifElse_else _bsonParse_applyOps + +#define _bsonParse_ifThenElse(Condition, Then, Else) \ + if ((Condition)) { \ + _bsonDSLDebug ("then:"); \ + _bsonParse_ifThen_##Then; \ + } else { \ + _bsonDSLDebug ("else:"); \ + _bsonParse_ifElse_##Else; \ + } + +#define _bsonParse_ifThen(Condition, Then) \ + if ((Condition)) { \ + _bsonDSLDebug ("%s", _bsonDSL_str (Then)); \ + _bsonParse_ifThen_##Then; \ + } else { \ + _bsonDSLDebug ("[else nothing]"); \ + } + +#define _bsonParseOperation_append \ + _bsonParseOperationDeferred_append _bsonDSL_nothing () +#define _bsonParseOperationDeferred_append(Doc, ...) \ + _bsonDSL_begin ("append to [%s] : %s", \ + _bsonDSL_str (Doc), \ + _bsonDSL_strElide (30, __VA_ARGS__)); \ + _bsonBuildAppend (Doc, __VA_ARGS__); \ + if (bsonBuildError) { \ + bsonParseError = bsonBuildError; \ + } \ + _bsonDSL_end + +#define _bsonVisit_applyOps _bsonVisit_applyOpsDeferred _bsonDSL_nothing () +#define _bsonVisit_applyOpsDeferred(...) \ + do { \ + _bsonDSL_mapMacro (_bsonVisit_applyOp, ~, __VA_ARGS__); \ + } while (0); + +#define bsonBuildArray(BSON, ...) \ + _bsonDSL_begin ("bsonBuildArray(%s, %s)", \ + _bsonDSL_str (BSON), \ + _bsonDSL_strElide (30, __VA_ARGS__)); \ + _bsonDSL_eval (_bsonBuildArray (BSON, __VA_ARGS__)); \ + _bsonDSL_end + +#define _bsonBuildArray(BSON, ...) \ + do { \ + _bsonDSL_disableWarnings (); \ + struct _bsonBuildContext_t _bbCtx = { \ + .doc = &(BSON), \ + .parent = _bsonBuildContextThreadLocalPtr, \ + .index = 0, \ + }; \ + _bsonBuildContextThreadLocalPtr = &_bbCtx; \ + _bsonBuildArrayWithCurrentContext (__VA_ARGS__); \ + _bsonBuildContextThreadLocalPtr = _bbCtx.parent; \ + _bsonDSL_restoreWarnings (); \ + } while (0) + +/** + * @brief Build a BSON document by appending to an existing bson_t document + * + * @param Pointer The document upon which to append + * @param ... The Document elements to append to the document + */ +#define bsonBuildAppend(BSON, ...) \ + _bsonDSL_eval (_bsonBuildAppend (BSON, __VA_ARGS__)) +#define _bsonBuildAppend(BSON, ...) \ + _bsonDSL_begin ("Appending to document '%s'", _bsonDSL_str (BSON)); \ + _bsonDSL_disableWarnings (); \ + /* Save the dsl context */ \ + struct _bsonBuildContext_t _bbCtx = { \ + .doc = &(BSON), \ + .parent = _bsonBuildContextThreadLocalPtr, \ + }; \ + /* Reset the context */ \ + _bsonBuildContextThreadLocalPtr = &_bbCtx; \ + bsonBuildError = NULL; \ + _bsonBuildAppendWithCurrentContext (__VA_ARGS__); \ + /* Restore the dsl context */ \ + _bsonBuildContextThreadLocalPtr = _bbCtx.parent; \ + _bsonDSL_restoreWarnings (); \ + _bsonDSL_end + +/** + * @brief Build a new BSON document and assign the value into the given + * pointer. + */ +#define bsonBuild(BSON, ...) \ + _bsonDSL_begin ("Build a new document for '%s'", _bsonDSL_str (BSON)); \ + bson_t *_bbDest = &(BSON); \ + bson_init (_bbDest); \ + bsonBuildAppend (*_bbDest, __VA_ARGS__); \ + _bsonDSL_end + +/** + * @brief Declare a variable and build it with the BSON DSL @see bsonBuild + */ +#define bsonBuildDecl(Variable, ...) \ + bson_t Variable = BSON_INITIALIZER; \ + bsonBuild (Variable, __VA_ARGS__) + + +struct _bsonBuildContext_t { + /// The document that is being built + bson_t *doc; + /// The key that is pending an append + const char *key; + /// The length of the string given in 'key' + int key_len; + /// The index of the array being built (if applicable) + size_t index; + /// A buffer for formatting key strings + char index_key_str[16]; + /// The parent context (if building a sub-document) + struct _bsonBuildContext_t *parent; +}; + +/// A pointer to the current thread's bsonBuild context +_bson_thread_local _bson_comdat struct _bsonBuildContext_t + *_bsonBuildContextThreadLocalPtr = NULL; + +struct _bsonVisitContext_t { + const bson_t *doc; + bson_iter_t iter; + const struct _bsonVisitContext_t *parent; + size_t index; +}; + +/// A pointer to the current thread's bsonVisit/bsonParse context +_bson_thread_local _bson_comdat struct _bsonVisitContext_t const + *_bsonVisitContextThreadLocalPtr = NULL; + +/** + * @brief The most recent error from a bsonBuild() DSL command. + * + * If NULL, no error occurred. Users can assign a value to this string to + * indicate failure. + */ +_bson_thread_local _bson_comdat const char *bsonBuildError = NULL; + +/** + * @brief The most recent error from a buildVisit() or bsonParse() DSL command. + * + * If NULL, no error occurred. Users can assign a value to this string to + * indicate an error. + * + * If this string becomes non-NULL, the current bsonVisit()/bsonParse() will + * halt and return. + * + * Upon entering a new bsonVisit()/bsonParse(), this will be reset to NULL. + */ +_bson_thread_local _bson_comdat const char *bsonParseError = NULL; + +#define _bsonDSLDebug(...) \ + _bson_dsl_debug (BSON_DSL_DEBUG, __FILE__, __LINE__, BSON_FUNC, __VA_ARGS__) + + +static BSON_INLINE bool +_bson_dsl_test_strequal (const char *string, bool case_sensitive) +{ + bson_iter_t it = bsonVisitIter; + if (bson_iter_type (&it) == BSON_TYPE_UTF8) { + uint32_t len; + const char *s = bson_iter_utf8 (&it, &len); + if (len != (uint32_t) strlen (string)) { + return false; + } + if (case_sensitive) { + return memcmp (string, s, len) == 0; + } else { + return bson_strcasecmp (string, s) == 0; + } + } + return false; +} + +static BSON_INLINE bool +_bson_dsl_key_is_anyof (const char *key, + const size_t keylen, + int case_sensitive, + ...) +{ + va_list va; + va_start (va, case_sensitive); + const char *str; + while ((str = va_arg (va, const char *))) { + size_t str_len = strlen (str); + if (str_len != keylen) { + continue; + } + if (case_sensitive) { + if (memcmp (str, key, str_len) == 0) { + va_end (va); + return true; + } + } else { + if (bson_strcasecmp (str, key) == 0) { + va_end (va); + return true; + } + } + } + va_end (va); + return false; +} + +static BSON_INLINE void +_bson_dsl_iter_as_doc (bson_t *into, const bson_iter_t *it) +{ + uint32_t len = 0; + const uint8_t *dataptr = NULL; + if (BSON_ITER_HOLDS_ARRAY (it)) { + bson_iter_array (it, &len, &dataptr); + } else if (BSON_ITER_HOLDS_DOCUMENT (it)) { + bson_iter_document (it, &len, &dataptr); + } + if (dataptr) { + BSON_ASSERT (bson_init_static (into, dataptr, len)); + } +} + +static BSON_INLINE bool +_bson_dsl_is_empty_bson (const bson_iter_t *it) +{ + bson_t d = BSON_INITIALIZER; + _bson_dsl_iter_as_doc (&d, it); + return d.len == 5; // Empty documents/arrays have byte-size of five +} + +static BSON_INLINE bool +_bson_dsl_iter_is_last_element (const bson_iter_t *it) +{ + bson_iter_t dup = *it; + return !bson_iter_next (&dup) && dup.err_off == 0; +} + +_bson_thread_local _bson_comdat int _bson_dsl_indent = 0; + +static BSON_INLINE void BSON_GNUC_PRINTF (5, 6) + _bson_dsl_debug (bool do_debug, + const char *file, + int line, + const char *func, + const char *string, + ...) +{ + if (do_debug) { + fprintf (stderr, "%s:%d: [%s] bson_dsl: ", file, line, func); + for (int i = 0; i < _bson_dsl_indent; ++i) { + fputs (" ", stderr); + } + va_list va; + va_start (va, string); + vfprintf (stderr, string, va); + va_end (va); + fputc ('\n', stderr); + fflush (stderr); + } +} + +static BSON_INLINE char *BSON_GNUC_PRINTF (2, 3) + _bson_dsl_errorf (char **const into, const char *const fmt, ...) +{ + if (*into) { + bson_free (*into); + *into = NULL; + } + va_list args; + va_start (args, fmt); + *into = bson_strdupv_printf (fmt, args); + va_end (args); + return *into; +} + +static BSON_INLINE void +_bson_dsl_dupPath (char **into) +{ + if (*into) { + bson_free (*into); + *into = NULL; + } + char *acc = bson_strdup (""); + for (const struct _bsonVisitContext_t *ctx = &bsonVisitContext; ctx; + ctx = ctx->parent) { + char *prev = acc; + if (ctx->parent && BSON_ITER_HOLDS_ARRAY (&ctx->parent->iter)) { + // We're an array element + acc = bson_strdup_printf ("[%d]%s", (int) ctx->index, prev); + } else { + // We're a document element + acc = bson_strdup_printf (".%s%s", bson_iter_key (&ctx->iter), prev); + } + bson_free (prev); + } + *into = bson_strdup_printf ("$%s", acc); + bson_free (acc); +} + +static BSON_INLINE const char * +_bsonVisitIterAs_cstr (void) +{ + return bson_iter_utf8 (&bsonVisitIter, NULL); +} + +static BSON_INLINE int32_t +_bsonVisitIterAs_int32 (void) +{ + return bson_iter_int32 (&bsonVisitIter); +} + +static BSON_INLINE bool +_bsonVisitIterAs_bool (void) +{ + return bson_iter_as_bool (&bsonVisitIter); +} + +static BSON_INLINE bool +_bsonVisitIterAs__Bool (void) +{ + return _bsonVisitIterAs_bool (); +} + +#define bsonAs(Type) _bsonDSL_paste (_bsonVisitIterAs_, Type) () + +/// Convert the given argument into a string without inhibitting macro expansion +#define _bsonDSL_str(...) _bsonDSL_str_1 (__VA_ARGS__) +// Empty quotes "" are to ensure a string appears. Old MSVC has a bug +// where empty #__VA_ARGS__ just vanishes. +#define _bsonDSL_str_1(...) "" #__VA_ARGS__ + +#define _bsonDSL_strElide(MaxLen, ...) \ + (strlen (_bsonDSL_str (__VA_ARGS__)) > (MaxLen) \ + ? "[...]" \ + : _bsonDSL_str (__VA_ARGS__)) + +/// Paste two tokens: +#define _bsonDSL_paste(a, ...) _bsonDSL_paste_impl (a, __VA_ARGS__) +#define _bsonDSL_paste_impl(a, ...) a##__VA_ARGS__ + +/// Paste three tokens: +#define _bsonDSL_paste3(a, b, c) _bsonDSL_paste (a, _bsonDSL_paste (b, c)) +/// Paste four tokens: +#define _bsonDSL_paste4(a, b, c, d) \ + _bsonDSL_paste (a, _bsonDSL_paste3 (b, c, d)) + +// clang-format off + +/// Now we need a MAP() macro. This idiom is common, but fairly opaque. Below is +/// some crazy preprocessor trickery to implement it. Fortunately, once we have +/// MAP(), the remainder of this file is straightforward. This implementation +/// isn't the simplest one possible, but is one that supports the old +/// non-compliant MSVC preprocessor. + +/* Expands to nothing. Used to defer a function-like macro and to ignore arguments */ +#define _bsonDSL_nothing(...) + +/// Expand to the 64th argument. See below for why this is useful. +#define _bsonDSL_pick64th(\ + _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ + _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ + _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ + _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ + _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ + _61, _62, _63, ...) \ + _63 + +/** + * @brief Expands to 1 if the given arguments contain any top-level commas, zero otherwise. + * + * There is an expansion of __VA_ARGS__, followed by 62 '1' arguments, followed + * by single '0'. If __VA_ARGS__ contains no commas, pick64th() will return the + * single zero. If __VA_ARGS__ contains any top-level commas, the series of ones + * will shift to the right and pick64th will return one of those ones. (This only + * works __VA_ARGS__ contains fewer than 62 commas, which is a somewhat reasonable + * limit.) The _bsonDSL_nothing() is a workaround for MSVC's bad preprocessor that + * expands __VA_ARGS__ incorrectly. + * + * If we have __VA_OPT__, this can be a lot simpler. + */ +#define _bsonDSL_hasComma(...) \ + _bsonDSL_pick64th \ + _bsonDSL_nothing() (__VA_ARGS__, \ + 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, 0, ~) + +/** + * Expands to a single comma if "invoked" as a function-like macro. + * (This will make sense, I promise.) + */ +#define _bsonDSL_commaIfRHSHasParens(...) , + +/** + * @brief Expand to 1 if given no arguments, otherwise 0. + * + * This could be done much more simply using __VA_OPT__, but we need to work on + * older compilers. + */ +#define _bsonDSL_isEmpty(...) \ + _bsonDSL_isEmpty_1(\ + /* Expands to '1' if __VA_ARGS__ contains any top-level commas */ \ + _bsonDSL_hasComma(__VA_ARGS__), \ + /* Expands to '1' if __VA_ARGS__ begins with a parenthesis, because \ + * that will cause an "invocation" of _bsonDSL_commaIfRHSHasParens, \ + * which immediately expands to a single comma. */ \ + _bsonDSL_hasComma(_bsonDSL_commaIfRHSHasParens __VA_ARGS__), \ + /* Expands to '1' if __VA_ARGS__ expands to a function-like macro name \ + * that then expands to anything containing a top-level comma */ \ + _bsonDSL_hasComma(__VA_ARGS__ ()), \ + /* Expands to '1' if __VA_ARGS__ expands to nothing. */ \ + _bsonDSL_hasComma(_bsonDSL_commaIfRHSHasParens __VA_ARGS__ ())) + +/** + * A helper for isEmpty(): If given (0, 0, 0, 1), expands as: + * - first: _bsonDSL_hasComma(_bsonDSL_isEmpty_CASE_0001) + * - then: _bsonDSL_hasComma(,) + * - then: 1 + * Given any other aruments: + * - first: _bsonDSL_hasComma(_bsonDSL_isEmpty_CASE_) + * - then: 0 + */ +#define _bsonDSL_isEmpty_1(_1, _2, _3, _4) \ + _bsonDSL_hasComma(_bsonDSL_paste(_bsonDSL_isEmpty_CASE_, _bsonDSL_paste4(_1, _2, _3, _4))) +#define _bsonDSL_isEmpty_CASE_0001 , + +/** + * @brief Expand to the first argument if `Cond` is 1, the second argument if `Cond` is 0 + */ +#define _bsonDSL_ifElse(Cond, IfTrue, IfFalse) \ + /* Suppress expansion of the two branches by using the '#' operator */ \ + _bsonDSL_nothing(#IfTrue, #IfFalse) \ + /* Concat the cond 1/0 with a prefix macro: */ \ + _bsonDSL_paste(_bsonDSL_ifElse_PICK_, Cond)(IfTrue, IfFalse) + +#define _bsonDSL_ifElse_PICK_1(IfTrue, IfFalse) \ + /* Expand the first operand, throw away the second */ \ + IfTrue _bsonDSL_nothing(#IfFalse) +#define _bsonDSL_ifElse_PICK_0(IfTrue, IfFalse) \ + /* Expand to the second operand, throw away the first */ \ + IfFalse _bsonDSL_nothing(#IfTrue) + +#ifdef _MSC_VER +// MSVC's "traditional" preprocessor requires many more expansion passes, +// but GNU and Clang are very slow when evaluating hugely nested expansions +// and generate massive macro expansion backtraces. +#define _bsonDSL_eval_1(...) __VA_ARGS__ +#define _bsonDSL_eval_2(...) _bsonDSL_eval_1(_bsonDSL_eval_1(_bsonDSL_eval_1(_bsonDSL_eval_1(_bsonDSL_eval_1(__VA_ARGS__))))) +#define _bsonDSL_eval_4(...) _bsonDSL_eval_2(_bsonDSL_eval_2(_bsonDSL_eval_2(_bsonDSL_eval_2(_bsonDSL_eval_2(__VA_ARGS__))))) +#define _bsonDSL_eval_8(...) _bsonDSL_eval_4(_bsonDSL_eval_4(_bsonDSL_eval_4(_bsonDSL_eval_4(_bsonDSL_eval_4(__VA_ARGS__))))) +#define _bsonDSL_eval_16(...) _bsonDSL_eval_8(_bsonDSL_eval_8(_bsonDSL_eval_8(_bsonDSL_eval_8(_bsonDSL_eval_8(__VA_ARGS__))))) +#define _bsonDSL_eval(...) _bsonDSL_eval_16(_bsonDSL_eval_16(_bsonDSL_eval_16(_bsonDSL_eval_16(_bsonDSL_eval_16(__VA_ARGS__))))) +#else +// Each level of "eval" applies double the expansions of the previous level. +#define _bsonDSL_eval_1(...) __VA_ARGS__ +#define _bsonDSL_eval_2(...) _bsonDSL_eval_1(_bsonDSL_eval_1(__VA_ARGS__)) +#define _bsonDSL_eval_4(...) _bsonDSL_eval_2(_bsonDSL_eval_2(__VA_ARGS__)) +#define _bsonDSL_eval_8(...) _bsonDSL_eval_4(_bsonDSL_eval_4(__VA_ARGS__)) +#define _bsonDSL_eval_16(...) _bsonDSL_eval_8(_bsonDSL_eval_8(__VA_ARGS__)) +#define _bsonDSL_eval_32(...) _bsonDSL_eval_16(_bsonDSL_eval_16(__VA_ARGS__)) +#define _bsonDSL_eval(...) _bsonDSL_eval_32(__VA_ARGS__) +#endif + +/** + * Finally, the Map() macro that allows us to do the magic, which we've been + * building up to all along. + * + * The dance with mapMacro_first, mapMacro_final, and _bsonDSL_nothing + * conditional on argument count is to prevent warnings from pre-C99 about + * passing no arguments to the '...' parameters. Yet again, if we had C99 and + * __VA_OPT__ this would be simpler. + */ +#define _bsonDSL_mapMacro(Action, Constant, ...) \ + /* Pick our first action based on the content of '...': */ \ + _bsonDSL_ifElse( \ + /* If given no arguments: */\ + _bsonDSL_isEmpty(__VA_ARGS__), \ + /* expand to _bsonDSL_nothing */ \ + _bsonDSL_nothing, \ + /* Otherwise, expand to mapMacro_first: */ \ + _bsonDSL_mapMacro_first) \ + /* Now "invoke" the chosen macro: */ \ + _bsonDSL_nothing() (Action, Constant, __VA_ARGS__) + +#define _bsonDSL_mapMacro_first(Action, Constant, ...) \ + /* Select our next step based on whether we have one or more arguments: */ \ + _bsonDSL_ifElse( \ + /* If '...' contains more than one argument (has a top-level comma): */ \ + _bsonDSL_hasComma(__VA_ARGS__), \ + /* Begin the mapMacro loop with mapMacro_A: */ \ + _bsonDSL_mapMacro_A, \ + /* Otherwise skip to the final step of the loop: */ \ + _bsonDSL_mapMacro_final) \ + /* Invoke the chosen macro, setting the counter to zero: */ \ + _bsonDSL_nothing() (Action, Constant, 0, __VA_ARGS__) + +/// Handle the last expansion in a mapMacro sequence. +#define _bsonDSL_mapMacro_final(Action, Constant, Counter, FinalElement) \ + Action(FinalElement, Constant, Counter) + +/** + * mapMacro_A and mapMacro_B are identical and just invoke each other. + */ +#define _bsonDSL_mapMacro_A(Action, Constant, Counter, Head, ...) \ + /* First evaluate the action once: */ \ + Action(Head, Constant, Counter) \ + /* Pick our next step: */ \ + _bsonDSL_ifElse( \ + /* If '...' contains more than one argument (has a top-level comma): */ \ + _bsonDSL_hasComma(__VA_ARGS__), \ + /* Jump to the other mapMacro: */ \ + _bsonDSL_mapMacro_B, \ + /* Otherwise go to mapMacro_final */ \ + _bsonDSL_mapMacro_final) \ + /* Invoke the next step of the map: */ \ + _bsonDSL_nothing() (Action, Constant, Counter + 1, __VA_ARGS__) + +#define _bsonDSL_mapMacro_B(Action, Constant, Counter, Head, ...) \ + Action(Head, Constant, Counter) \ + _bsonDSL_ifElse(_bsonDSL_hasComma(__VA_ARGS__), _bsonDSL_mapMacro_A, _bsonDSL_mapMacro_final) \ + _bsonDSL_nothing() (Action, Constant, Counter + 1, __VA_ARGS__) + +// clang-format on + + +#endif // BSON_BSON_DSL_H_INCLUDED diff --git a/src/common/common-md5.c b/src/common/common-md5.c index e72005c6..c726b918 100644 --- a/src/common/common-md5.c +++ b/src/common/common-md5.c @@ -172,12 +172,12 @@ bson_md5_process (bson_md5_t *md5, const uint8_t *data) if (!((data - (const uint8_t *) 0) & 3)) { /* data are properly aligned */ #ifdef __clang__ -/*IGNORE*/ #pragma clang diagnostic push -/*IGNORE*/ #pragma clang diagnostic ignored "-Wcast-align" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcast-align" #endif X = (const uint32_t *) data; #ifdef __clang__ -/*IGNORE*/ #pragma clang diagnostic pop +#pragma clang diagnostic pop #endif } else { /* not aligned */ diff --git a/src/common/common-prelude.h b/src/common/common-prelude.h index efc18bcd..3fbd0cb2 100644 --- a/src/common/common-prelude.h +++ b/src/common/common-prelude.h @@ -19,7 +19,8 @@ #error "Only or can be included directly." #endif -#define COMMON_NAME_1(a, b) a##_##b +#define COMMON_NAME_1(a, b) COMMON_NAME_2 (a, b) +#define COMMON_NAME_2(a, b) a##_##b #if defined(MCOMMON_NAME_PREFIX) && !defined(__INTELLISENSE__) #define COMMON_NAME(Name) COMMON_NAME_1 (MCOMMON_NAME_PREFIX, Name) diff --git a/src/common/common-thread-private.h b/src/common/common-thread-private.h index 17491f26..300bdb50 100644 --- a/src/common/common-thread-private.h +++ b/src/common/common-thread-private.h @@ -38,7 +38,10 @@ BSON_BEGIN_DECLS #define BSON_ONCE_FUN(n) void n (void) #define BSON_ONCE_RETURN return #define BSON_ONCE_INIT PTHREAD_ONCE_INIT -#define bson_once pthread_once +#define bson_once(o, c) \ + do { \ + BSON_ASSERT (pthread_once ((o), (c)) == 0); \ + } while (0) #define bson_once_t pthread_once_t #define bson_thread_t pthread_t #define BSON_THREAD_FUN(_function_name, _arg_name) \ @@ -54,11 +57,27 @@ BSON_BEGIN_DECLS #ifndef MONGOC_ENABLE_DEBUG_ASSERTIONS -#define bson_mutex_destroy pthread_mutex_destroy -#define bson_mutex_init(_n) pthread_mutex_init ((_n), NULL) -#define bson_mutex_lock pthread_mutex_lock +#define bson_mutex_destroy(m) \ + do { \ + BSON_ASSERT (pthread_mutex_destroy ((m)) == 0); \ + } while (0) + +#define bson_mutex_init(_n) \ + do { \ + BSON_ASSERT (pthread_mutex_init ((_n), NULL) == 0); \ + } while (0) + +#define bson_mutex_lock(m) \ + do { \ + BSON_ASSERT (pthread_mutex_lock ((m)) == 0); \ + } while (0) + #define bson_mutex_t pthread_mutex_t -#define bson_mutex_unlock pthread_mutex_unlock + +#define bson_mutex_unlock(m) \ + do { \ + BSON_ASSERT (pthread_mutex_unlock ((m)) == 0); \ + } while (0) #else typedef struct { @@ -67,28 +86,28 @@ typedef struct { bool valid_tid; } bson_mutex_t; -#define bson_mutex_destroy(mutex) \ - do { \ - pthread_mutex_destroy (&(mutex)->wrapped_mutex); \ +#define bson_mutex_destroy(mutex) \ + do { \ + BSON_ASSERT (pthread_mutex_destroy (&(mutex)->wrapped_mutex) == 0); \ } while (0); -#define bson_mutex_init(mutex) \ - do { \ - pthread_mutex_init (&(mutex)->wrapped_mutex, NULL); \ - (mutex)->valid_tid = false; \ +#define bson_mutex_init(mutex) \ + do { \ + BSON_ASSERT (pthread_mutex_init (&(mutex)->wrapped_mutex, NULL) == 0); \ + (mutex)->valid_tid = false; \ } while (0); -#define bson_mutex_lock(mutex) \ - do { \ - pthread_mutex_lock (&(mutex)->wrapped_mutex); \ - (mutex)->lock_owner = pthread_self (); \ - (mutex)->valid_tid = true; \ +#define bson_mutex_lock(mutex) \ + do { \ + BSON_ASSERT (pthread_mutex_lock (&(mutex)->wrapped_mutex) == 0); \ + (mutex)->lock_owner = pthread_self (); \ + (mutex)->valid_tid = true; \ } while (0); -#define bson_mutex_unlock(mutex) \ - do { \ - (mutex)->valid_tid = false; \ - pthread_mutex_unlock (&(mutex)->wrapped_mutex); \ +#define bson_mutex_unlock(mutex) \ + do { \ + (mutex)->valid_tid = false; \ + BSON_ASSERT (pthread_mutex_unlock (&(mutex)->wrapped_mutex) == 0); \ } while (0); #endif @@ -104,7 +123,10 @@ typedef struct { #define bson_mutex_lock EnterCriticalSection #define bson_mutex_t CRITICAL_SECTION #define bson_mutex_unlock LeaveCriticalSection -#define bson_once(o, c) InitOnceExecuteOnce (o, c, NULL, NULL) +#define bson_once(o, c) \ + do { \ + BSON_ASSERT (InitOnceExecuteOnce ((o), (c), NULL, NULL)); \ + } while (0) #define bson_once_t INIT_ONCE #define bson_thread_t HANDLE #define BSON_THREAD_FUN(_function_name, _arg_name) \ @@ -119,6 +141,9 @@ typedef struct { * libbson and libmongoc statically. */ int mcommon_thread_join (bson_thread_t thread); +// mcommon_thread_create returns 0 on success. Returns a non-zero error code on +// error. Callers may use `bson_strerror_r` to get an error message from the +// returned error code. int mcommon_thread_create (bson_thread_t *thread, BSON_THREAD_FUN_TYPE (func), @@ -147,42 +172,42 @@ static BSON_INLINE void bson_shared_mutex_init (bson_shared_mutex_t *mtx) { BSON_IF_WINDOWS (InitializeSRWLock (&mtx->native)); - BSON_IF_POSIX (pthread_rwlock_init (&mtx->native, NULL)); + BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_init (&mtx->native, NULL) == 0);) } static BSON_INLINE void bson_shared_mutex_destroy (bson_shared_mutex_t *mtx) { BSON_IF_WINDOWS ((void) mtx;) - BSON_IF_POSIX (pthread_rwlock_destroy (&mtx->native);) + BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_destroy (&mtx->native) == 0);) } static BSON_INLINE void bson_shared_mutex_lock_shared (bson_shared_mutex_t *mtx) { BSON_IF_WINDOWS (AcquireSRWLockShared (&mtx->native);) - BSON_IF_POSIX (pthread_rwlock_rdlock (&mtx->native);) + BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_rdlock (&mtx->native) == 0);) } static BSON_INLINE void bson_shared_mutex_lock (bson_shared_mutex_t *mtx) { BSON_IF_WINDOWS (AcquireSRWLockExclusive (&mtx->native);) - BSON_IF_POSIX (pthread_rwlock_wrlock (&mtx->native);) + BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_wrlock (&mtx->native) == 0);) } static BSON_INLINE void bson_shared_mutex_unlock (bson_shared_mutex_t *mtx) { BSON_IF_WINDOWS (ReleaseSRWLockExclusive (&mtx->native);) - BSON_IF_POSIX (pthread_rwlock_unlock (&mtx->native);) + BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_unlock (&mtx->native) == 0);) } static BSON_INLINE void bson_shared_mutex_unlock_shared (bson_shared_mutex_t *mtx) { BSON_IF_WINDOWS (ReleaseSRWLockShared (&mtx->native);) - BSON_IF_POSIX (pthread_rwlock_unlock (&mtx->native);) + BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_unlock (&mtx->native) == 0);) } BSON_END_DECLS diff --git a/src/common/common-thread.c b/src/common/common-thread.c index 514a9c9d..037a6490 100644 --- a/src/common/common-thread.c +++ b/src/common/common-thread.c @@ -16,12 +16,17 @@ #include "common-thread-private.h" +#include + #if defined(BSON_OS_UNIX) int mcommon_thread_create (bson_thread_t *thread, BSON_THREAD_FUN_TYPE (func), void *arg) { + BSON_ASSERT_PARAM (thread); + BSON_ASSERT_PARAM (func); + BSON_ASSERT (arg || true); // optional. return pthread_create (thread, NULL, func, arg); } int @@ -45,9 +50,13 @@ mcommon_thread_create (bson_thread_t *thread, BSON_THREAD_FUN_TYPE (func), void *arg) { + BSON_ASSERT_PARAM (thread); + BSON_ASSERT_PARAM (func); + BSON_ASSERT (arg || true); // optional. + *thread = (HANDLE) _beginthreadex (NULL, 0, func, arg, 0, NULL); if (0 == *thread) { - return 1; + return errno; } return 0; } diff --git a/src/kms/hexlify.c b/src/kms/hexlify.c index 941fc93d..2d709271 100644 --- a/src/kms/hexlify.c +++ b/src/kms/hexlify.c @@ -37,3 +37,31 @@ hexlify (const uint8_t *buf, size_t len) return hex_chars; } + +/* Returns -1 on error. */ +int +unhexlify (const char *in, size_t len) +{ + int i; + int byte; + int total = 0; + int multiplier = 1; + + for (i = (int) len - 1; i >= 0; i--) { + char c = *(in + i); + + if (c >= '0' && c <= '9') { + byte = c - 48; + } else if (c >= 'a' && c <= 'f') { + byte = c - 97 + 10; + } else if (c >= 'A' && c <= 'F') { + byte = c - 65 + 10; + } else { + return -1; + } + + total += byte * multiplier; + multiplier *= 16; + } + return total; +} diff --git a/src/kms/hexlify.h b/src/kms/hexlify.h index a6a504eb..60bc93ea 100644 --- a/src/kms/hexlify.h +++ b/src/kms/hexlify.h @@ -19,3 +19,6 @@ char * hexlify (const uint8_t *buf, size_t len); + +int +unhexlify (const char *in, size_t len); \ No newline at end of file diff --git a/src/kms/kms_azure_request.c b/src/kms/kms_azure_request.c new file mode 100644 index 00000000..5ce7488f --- /dev/null +++ b/src/kms/kms_azure_request.c @@ -0,0 +1,219 @@ +/* + * Copyright 2020-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kms_message/kms_azure_request.h" + +#include "kms_message/kms_b64.h" +#include "kms_message_private.h" +#include "kms_request_opt_private.h" +#include "kms_request_str.h" + +/* + * Request has the following form: + * + * POST /{tenant ID}/oauth2/v2.0/token HTTP/1.1 + * Host: {host of identify platform URL} + * Content-Type: application/x-www-form-urlencoded + * + * client_id={client ID} + * &scope=https%3A%2F%2Fvault.azure.net%2F.default + * &client_secret={client secret} + * &grant_type=client_credentials +*/ +kms_request_t * +kms_azure_request_oauth_new (const char *host, + const char *scope, + const char *tenant_id, + const char *client_id, + const char *client_secret, + const kms_request_opt_t *opt) +{ + char *path_and_query = NULL; + char *payload = NULL; + kms_request_t *req; + kms_request_str_t *str; + + str = kms_request_str_new (); + kms_request_str_appendf (str, "/%s/oauth2/v2.0/token", tenant_id); + path_and_query = kms_request_str_detach (str); + str = kms_request_str_new (); + kms_request_str_appendf ( + str, + "client_id=%s&scope=%s&client_secret=%s&grant_type=client_credentials", + client_id, + scope, + client_secret); + payload = kms_request_str_detach (str); + + req = kms_request_new ("POST", path_and_query, opt); + + if (opt->provider != KMS_REQUEST_PROVIDER_AZURE) { + KMS_ERROR (req, "Expected KMS request with provider type: Azure"); + goto done; + } + + if (kms_request_get_error (req)) { + goto done; + } + + if (!kms_request_add_header_field ( + req, "Content-Type", "application/x-www-form-urlencoded")) { + goto done; + } + if (!kms_request_add_header_field (req, "Host", host)) { + goto done; + } + if (!kms_request_add_header_field (req, "Accept", "application/json")) { + goto done; + } + + if (!kms_request_append_payload (req, payload, strlen (payload))) { + goto done; + } + +done: + kms_request_free_string (path_and_query); + kms_request_free_string (payload); + return req; +} + +static kms_request_t * +_wrap_unwrap_common (const char *wrap_unwrap, + const char *host, + const char *access_token, + const char *key_name, + const char *key_version, + const uint8_t *value, + size_t value_len, + const kms_request_opt_t *opt) +{ + char *path_and_query = NULL; + char *payload = NULL; + char *bearer_token_value = NULL; + char *value_base64url = NULL; + kms_request_t *req; + kms_request_str_t *str; + + str = kms_request_str_new (); + /* {vaultBaseUrl}/keys/{key-name}/{key-version}/wrapkey?api-version=7.1 */ + kms_request_str_appendf (str, + "/keys/%s/%s/%s?api-version=7.1", + key_name, + key_version ? key_version : "", + wrap_unwrap); + path_and_query = kms_request_str_detach (str); + + req = kms_request_new ("POST", path_and_query, opt); + + if (opt->provider != KMS_REQUEST_PROVIDER_AZURE) { + KMS_ERROR (req, "Expected KMS request with provider type: Azure"); + goto done; + } + + if (kms_request_get_error (req)) { + goto done; + } + + value_base64url = kms_message_raw_to_b64url (value, value_len); + if (!value_base64url) { + KMS_ERROR (req, "Could not bases64url-encode plaintext"); + goto done; + } + + str = kms_request_str_new (); + kms_request_str_appendf ( + str, "{\"alg\": \"RSA-OAEP-256\", \"value\": \"%s\"}", value_base64url); + payload = kms_request_str_detach (str); + str = kms_request_str_new (); + kms_request_str_appendf (str, "Bearer %s", access_token); + bearer_token_value = kms_request_str_detach (str); + if (!kms_request_add_header_field ( + req, "Authorization", bearer_token_value)) { + goto done; + } + if (!kms_request_add_header_field ( + req, "Content-Type", "application/json")) { + goto done; + } + if (!kms_request_add_header_field (req, "Host", host)) { + goto done; + } + if (!kms_request_add_header_field (req, "Accept", "application/json")) { + goto done; + } + + if (!kms_request_append_payload (req, payload, strlen (payload))) { + goto done; + } + +done: + kms_request_free_string (path_and_query); + kms_request_free_string (payload); + kms_request_free_string (bearer_token_value); + kms_request_free_string (value_base64url); + return req; +} + +/* + * Request has the following form: + * + * POST /keys/{key-name}/{key-version}/wrapkey?api-version=7.1 + * Host: {host of key vault endpoint} + * Authentication: Bearer {token} + * Content-Type: application/json + * + * { + * "alg": "RSA-OAEP-256" + * "value": "base64url encoded data" + * } + */ +kms_request_t * +kms_azure_request_wrapkey_new (const char *host, + const char *access_token, + const char *key_name, + const char *key_version, + const uint8_t *plaintext, + size_t plaintext_len, + const kms_request_opt_t *opt) +{ + return _wrap_unwrap_common ("wrapkey", + host, + access_token, + key_name, + key_version, + plaintext, + plaintext_len, + opt); +} + +kms_request_t * +kms_azure_request_unwrapkey_new (const char *host, + const char *access_token, + const char *key_name, + const char *key_version, + const uint8_t *ciphertext, + size_t ciphertext_len, + const kms_request_opt_t *opt) +{ + return _wrap_unwrap_common ("unwrapkey", + host, + access_token, + key_name, + key_version, + ciphertext, + ciphertext_len, + opt); +} \ No newline at end of file diff --git a/src/kms/kms_b64.c b/src/kms/kms_b64.c index 713545d9..3df804b2 100644 --- a/src/kms/kms_b64.c +++ b/src/kms/kms_b64.c @@ -41,12 +41,13 @@ */ #include -#include "kms_message/kms_message.h" -#include "kms_message/kms_b64.h" +#include +#include +#include -#define Assert(Cond) \ - if (!(Cond)) \ - abort () +#include "kms_message/kms_b64.h" +#include "kms_message/kms_message.h" +#include "kms_message_private.h" static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -132,13 +133,13 @@ kms_message_b64_ntop (uint8_t const *src, srclength -= 3; output[0] = input[0] >> 2; - output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); - output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[1] = (uint8_t) (((input[0] & 0x03) << 4) + (input[1] >> 4)); + output[2] = (uint8_t) (((input[1] & 0x0f) << 2) + (input[2] >> 6)); output[3] = input[2] & 0x3f; - Assert (output[0] < 64); - Assert (output[1] < 64); - Assert (output[2] < 64); - Assert (output[3] < 64); + KMS_ASSERT (output[0] < 64); + KMS_ASSERT (output[1] < 64); + KMS_ASSERT (output[2] < 64); + KMS_ASSERT (output[3] < 64); if (datalength + 4 > targsize) { return -1; @@ -158,11 +159,11 @@ kms_message_b64_ntop (uint8_t const *src, input[i] = *src++; } output[0] = input[0] >> 2; - output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); - output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); - Assert (output[0] < 64); - Assert (output[1] < 64); - Assert (output[2] < 64); + output[1] = (uint8_t) (((input[0] & 0x03) << 4) + (input[1] >> 4)); + output[2] = (uint8_t) (((input[1] & 0x0f) << 2) + (input[2] >> 6)); + KMS_ASSERT (output[0] < 64); + KMS_ASSERT (output[1] < 64); + KMS_ASSERT (output[2] < 64); if (datalength + 4 > targsize) { return -1; @@ -263,7 +264,7 @@ static const uint8_t b64rmap_invalid = 0xff; void kms_message_b64_initialize_rmap (void) { - int i; + uint16_t i; unsigned char ch; /* Null: end of string, stop parsing */ @@ -284,7 +285,7 @@ kms_message_b64_initialize_rmap (void) /* Fill reverse mapping for base64 chars */ for (i = 0; Base64[i] != '\0'; ++i) - b64rmap[(uint8_t) Base64[i]] = i; + b64rmap[(uint8_t) Base64[i]] = (uint8_t) i; } static int @@ -315,14 +316,14 @@ b64_pton_do (char const *src, uint8_t *target, size_t targsize) case 0: if ((size_t) tarindex >= targsize) return (-1); - target[tarindex] = ofs << 2; + target[tarindex] = (uint8_t) (ofs << 2); state = 1; break; case 1: if ((size_t) tarindex + 1 >= targsize) return (-1); target[tarindex] |= ofs >> 4; - target[tarindex + 1] = (ofs & 0x0f) << 4; + target[tarindex + 1] = (uint8_t) ((ofs & 0x0f) << 4); tarindex++; state = 2; break; @@ -330,7 +331,7 @@ b64_pton_do (char const *src, uint8_t *target, size_t targsize) if ((size_t) tarindex + 1 >= targsize) return (-1); target[tarindex] |= ofs >> 2; - target[tarindex + 1] = (ofs & 0x03) << 6; + target[tarindex + 1] = (uint8_t) ((ofs & 0x03) << 6); tarindex++; state = 3; break; @@ -505,3 +506,149 @@ kms_message_b64_pton (char const *src, uint8_t *target, size_t targsize) else return b64_pton_len (src); } + +int +kms_message_b64_to_b64url (const char *src, + size_t srclength, + char *target, + size_t targsize) +{ + size_t i; + + for (i = 0; i < srclength; i++) { + if (i >= targsize) { + return -1; + } + + target[i] = src[i]; + if (target[i] == '+') { + target[i] = '-'; + } else if (target[i] == '/') { + target[i] = '_'; + } + } + + /* NULL terminate if room. */ + if (i < targsize) { + target[i] = '\0'; + } + + return (int) i; +} + +int +kms_message_b64url_to_b64 (const char *src, + size_t srclength, + char *target, + size_t targsize) +{ + size_t i; + size_t boundary; + + for (i = 0; i < srclength; i++) { + if (i >= targsize) { + return -1; + } + + target[i] = src[i]; + if (target[i] == '-') { + target[i] = '+'; + } else if (target[i] == '_') { + target[i] = '/'; + } + } + + /* Pad to four byte boundary. */ + boundary = 4 * ((i + 3) / 4); + for (; i < boundary; i++) { + if (i >= targsize) { + return -1; + } + target[i] = '='; + } + + /* NULL terminate if room. */ + if (i < targsize) { + target[i] = '\0'; + } + + return (int) i; +} + +char * +kms_message_raw_to_b64 (const uint8_t *raw, size_t raw_len) +{ + char *b64; + size_t b64_len; + + b64_len = (raw_len / 3 + 1) * 4 + 1; + b64 = malloc (b64_len); + memset (b64, 0, b64_len); + if (-1 == kms_message_b64_ntop (raw, raw_len, b64, b64_len)) { + free (b64); + return NULL; + } + return b64; +} + +uint8_t * +kms_message_b64_to_raw (const char *b64, size_t *out) +{ + uint8_t *raw; + int ret; + size_t b64len; + + b64len = strlen (b64); + raw = (uint8_t *) malloc (b64len + 1); + memset (raw, 0, b64len + 1); + ret = kms_message_b64_pton (b64, raw, b64len); + if (ret > 0) { + *out = (size_t) ret; + return raw; + } + free (raw); + return NULL; +} + +char * +kms_message_raw_to_b64url (const uint8_t *raw, size_t raw_len) +{ + char *b64; + size_t b64len; + + b64 = kms_message_raw_to_b64 (raw, raw_len); + if (!b64) { + return NULL; + } + + b64len = strlen (b64); + if (-1 == kms_message_b64_to_b64url (b64, b64len, b64, b64len)) { + free (b64); + return NULL; + } + + return b64; +} + +uint8_t * +kms_message_b64url_to_raw (const char *b64url, size_t *out) +{ + char *b64; + size_t capacity; + uint8_t *raw; + size_t b64urllen; + + b64urllen = strlen(b64url); + /* Add four for padding '=' characters. */ + capacity = b64urllen + 4; + b64 = malloc (capacity); + memset (b64, 0, capacity); + if (-1 == + kms_message_b64url_to_b64 (b64url, b64urllen, b64, capacity)) { + free (b64); + return NULL; + } + raw = kms_message_b64_to_raw (b64, out); + free (b64); + return raw; +} diff --git a/src/kms/kms_caller_identity_request.c b/src/kms/kms_caller_identity_request.c index d4c12188..371d2d7b 100644 --- a/src/kms/kms_caller_identity_request.c +++ b/src/kms/kms_caller_identity_request.c @@ -40,7 +40,10 @@ kms_caller_identity_request_new (const kms_request_opt_t *opt) payload = kms_request_str_new (); kms_request_str_appendf (payload, "Action=GetCallerIdentity&Version=2011-06-15"); - kms_request_append_payload (request, payload->str, payload->len); + if (!kms_request_append_payload (request, payload->str, payload->len)) { + KMS_ERROR (request, "Could not append payload"); + goto done; + } done: kms_request_str_destroy (payload); diff --git a/src/kms/kms_crypto.h b/src/kms/kms_crypto.h index bf20be99..1045f279 100644 --- a/src/kms/kms_crypto.h +++ b/src/kms/kms_crypto.h @@ -31,7 +31,14 @@ typedef struct { const char *input, size_t len, unsigned char *hash_out); + bool (*sign_rsaes_pkcs1_v1_5) (void *sign_ctx, + const char *private_key, + size_t private_key_len, + const char *input, + size_t input_len, + unsigned char *signature_out); void *ctx; + void *sign_ctx; } _kms_crypto_t; int @@ -51,4 +58,13 @@ kms_sha256_hmac (void *ctx, size_t len, unsigned char *hash_out); +/* signature_out must be a preallocated buffer of 256 bytes (or greater). */ +bool +kms_sign_rsaes_pkcs1_v1_5 (void *sign_ctx, + const char *private_key, + size_t private_key_len, + const char *input, + size_t input_len, + unsigned char *signature_out); + #endif /* KMS_MESSAGE_KMS_CRYPTO_H */ diff --git a/src/kms/kms_crypto_apple.c b/src/kms/kms_crypto_apple.c index 0e496011..d061416f 100644 --- a/src/kms/kms_crypto_apple.c +++ b/src/kms/kms_crypto_apple.c @@ -15,12 +15,16 @@ */ #include "kms_crypto.h" +#include "kms_message_private.h" /* KMS_ASSERT */ #ifdef KMS_MESSAGE_ENABLE_CRYPTO_COMMON_CRYPTO #include #include - +#include +#include +#include +#include int kms_crypto_init (void) @@ -41,7 +45,8 @@ kms_sha256 (void *unused_ctx, { CC_SHA256_CTX ctx; CC_SHA256_Init (&ctx); - CC_SHA256_Update (&ctx, input, len); + KMS_ASSERT (len <= (size_t) UINT32_MAX); + CC_SHA256_Update (&ctx, input, (uint32_t) len); CC_SHA256_Final (hash_out, &ctx); return true; } @@ -58,4 +63,97 @@ kms_sha256_hmac (void *unused_ctx, return true; } +static void +safe_CFRelease (CFTypeRef ptr) +{ + if (ptr) { + CFRelease (ptr); + } +} + +bool +kms_sign_rsaes_pkcs1_v1_5 (void *unused_ctx, + const char *private_key, + size_t private_key_len, + const char *input, + size_t input_len, + unsigned char *signature_out) +{ + CFDataRef key_data_ref = NULL; + CFDataRef pass_ref = NULL; + SecItemImportExportKeyParameters import_params; + OSStatus status; + /* TODO: I think the expected format should be kSecFormatWrappedPKCS8, but + * GCP keys appear to only load for kSecFormatBSAFE. */ + SecExternalFormat format = kSecFormatUnknown; + SecExternalItemType type = kSecItemTypePrivateKey; + CFArrayRef out_ref = NULL; + SecKeyRef key_ref = NULL; + CFDataRef data_to_sign_ref = NULL; + CFErrorRef error_ref; + CFDataRef signature_ref = NULL; + bool ret = false; + + key_data_ref = CFDataCreate (NULL /* default allocator */, + (const uint8_t *) private_key, + (CFIndex) private_key_len); + if (!key_data_ref) { + goto cleanup; + } + memset (&import_params, 0, sizeof (SecItemImportExportKeyParameters)); + import_params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; + + /* Give an empty password. SecItemImport returns an error expecting a + * password. */ + pass_ref = CFDataCreate (NULL, NULL, 0); + if (!pass_ref) { + goto cleanup; + } + import_params.passphrase = (CFTypeRef) pass_ref; + + status = SecItemImport (key_data_ref, + NULL /* extension. */, + &format, + &type, + 0, + &import_params, + NULL /* keychain */, + &out_ref); + if (status != errSecSuccess) { + goto cleanup; + } + if (1 != CFArrayGetCount (out_ref)) { + goto cleanup; + } + + key_ref = (SecKeyRef) CFArrayGetValueAtIndex (out_ref, 0); + KMS_ASSERT (input_len <= (size_t) LONG_MAX); + data_to_sign_ref = + CFDataCreate (NULL, (const uint8_t *) input, (long) input_len); + if (!data_to_sign_ref) { + goto cleanup; + } + error_ref = NULL; + signature_ref = + SecKeyCreateSignature (key_ref, + kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256, + data_to_sign_ref, + &error_ref); + if (!signature_ref) { + goto cleanup; + } + memcpy (signature_out, + CFDataGetBytePtr (signature_ref), + (size_t) CFDataGetLength (signature_ref)); + + ret = true; +cleanup: + safe_CFRelease (key_data_ref); + safe_CFRelease (pass_ref); + safe_CFRelease (out_ref); + safe_CFRelease (data_to_sign_ref); + safe_CFRelease (signature_ref); + return ret; +} + #endif /* KMS_MESSAGE_ENABLE_CRYPTO_COMMON_CRYPTO */ diff --git a/src/kms/kms_crypto_libcrypto.c b/src/kms/kms_crypto_libcrypto.c index d5408e86..16a06fac 100644 --- a/src/kms/kms_crypto_libcrypto.c +++ b/src/kms/kms_crypto_libcrypto.c @@ -15,12 +15,14 @@ */ #include "kms_crypto.h" +#include "kms_message_private.h" #ifdef KMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO #include #include #include +#include /* INT_MAX, LONG_MAX */ #if OPENSSL_VERSION_NUMBER < 0x10100000L || \ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) @@ -82,13 +84,59 @@ kms_sha256_hmac (void *unused_ctx, size_t len, unsigned char *hash_out) { + KMS_ASSERT (key_len <= INT_MAX); return HMAC (EVP_sha256 (), key_input, - key_len, + (int) key_len, (unsigned char *) input, len, hash_out, NULL) != NULL; } +bool +kms_sign_rsaes_pkcs1_v1_5 (void *unused_ctx, + const char *private_key, + size_t private_key_len, + const char *input, + size_t input_len, + unsigned char *signature_out) +{ + EVP_MD_CTX *ctx; + EVP_PKEY *pkey = NULL; + bool ret = false; + size_t signature_out_len = 256; + + ctx = EVP_MD_CTX_new (); + KMS_ASSERT (private_key_len <= LONG_MAX); + pkey = d2i_PrivateKey (EVP_PKEY_RSA, + NULL, + (const unsigned char **) &private_key, + (long) private_key_len); + if (!pkey) { + goto cleanup; + } + + ret = EVP_DigestSignInit (ctx, NULL, EVP_sha256 (), NULL /* engine */, pkey); + if (ret != 1) { + goto cleanup; + } + + ret = EVP_DigestSignUpdate (ctx, input, input_len); + if (ret != 1) { + goto cleanup; + } + + ret = EVP_DigestSignFinal (ctx, signature_out, &signature_out_len); + if (ret != 1) { + goto cleanup; + } + + ret = true; +cleanup: + EVP_MD_CTX_free (ctx); + EVP_PKEY_free (pkey); + return ret; +} + #endif /* KMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO */ diff --git a/src/kms/kms_crypto_none.c b/src/kms/kms_crypto_none.c index 94da5abd..422dde52 100644 --- a/src/kms/kms_crypto_none.c +++ b/src/kms/kms_crypto_none.c @@ -19,13 +19,13 @@ #ifndef KMS_MESSAGE_ENABLE_CRYPTO int -kms_crypto_init () +kms_crypto_init (void) { return 0; } void -kms_crypto_cleanup () +kms_crypto_cleanup (void) { } @@ -51,4 +51,15 @@ kms_sha256_hmac (void *unused_ctx, return false; } +bool +kms_sign_rsaes_pkcs1_v1_5 (void *unused_ctx, + const char *private_key, + size_t private_key_len, + const char *input, + size_t input_len, + unsigned char *signature_out) { + /* only gets called if hooks were mistakenly not set */ + return false; +} + #endif /* KMS_MESSAGE_ENABLE_CRYPTO */ diff --git a/src/kms/kms_crypto_windows.c b/src/kms/kms_crypto_windows.c index 8177b0dd..caee9bd1 100644 --- a/src/kms/kms_crypto_windows.c +++ b/src/kms/kms_crypto_windows.c @@ -38,12 +38,16 @@ #include #include +#include static BCRYPT_ALG_HANDLE _algoSHA256 = 0; static BCRYPT_ALG_HANDLE _algoSHA256Hmac = 0; +static BCRYPT_ALG_HANDLE _algoRSA = 0; + +#define SHA_256_HASH_LEN 32 int -kms_crypto_init () +kms_crypto_init (void) { if (BCryptOpenAlgorithmProvider ( &_algoSHA256, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != @@ -59,14 +63,21 @@ kms_crypto_init () return 2; } + if (BCryptOpenAlgorithmProvider ( + &_algoRSA, BCRYPT_RSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != + STATUS_SUCCESS) { + return 3; + } + return 0; } void -kms_crypto_cleanup () +kms_crypto_cleanup (void) { (void) BCryptCloseAlgorithmProvider (_algoSHA256, 0); (void) BCryptCloseAlgorithmProvider (_algoSHA256Hmac, 0); + (void) BCryptCloseAlgorithmProvider (_algoRSA, 0); } bool @@ -133,4 +144,125 @@ kms_sha256_hmac (void *unused_ctx, return status == STATUS_SUCCESS ? 1 : 0; } +bool +kms_sign_rsaes_pkcs1_v1_5 (void *unused_ctx, + const char *private_key, + size_t private_key_len, + const char *input, + size_t input_len, + unsigned char *signature_out) +{ + bool success = false; + bool ret = false; + LPBYTE blob_private = NULL; + DWORD blob_private_len = 0; + LPBYTE raw_private = NULL; + DWORD raw_private_len = 0; + + NTSTATUS status; + BCRYPT_KEY_HANDLE hKey = NULL; + BCRYPT_PKCS1_PADDING_INFO padding_PKCS1; + + unsigned char *hash_value = NULL; + DWORD hash_length = 256; + + success = CryptDecodeObjectEx (X509_ASN_ENCODING, + PKCS_PRIVATE_KEY_INFO, + private_key, + (DWORD) private_key_len, + 0, + NULL, + NULL, + &blob_private_len); + if (!success) { + goto cleanup; + } + + blob_private = (LPBYTE) calloc (1, blob_private_len); + + success = CryptDecodeObjectEx (X509_ASN_ENCODING, + PKCS_PRIVATE_KEY_INFO, + private_key, + (DWORD) private_key_len, + 0, + NULL, + blob_private, + &blob_private_len); + if (!success) { + goto cleanup; + } + + CRYPT_PRIVATE_KEY_INFO *privateKeyInfo = + (CRYPT_PRIVATE_KEY_INFO *) blob_private; + + success = CryptDecodeObjectEx (X509_ASN_ENCODING, + PKCS_RSA_PRIVATE_KEY, + privateKeyInfo->PrivateKey.pbData, + (DWORD) privateKeyInfo->PrivateKey.cbData, + 0, + NULL, + NULL, + &raw_private_len); + if (!success) { + goto cleanup; + } + + raw_private = (LPBYTE) calloc (1, raw_private_len); + + success = CryptDecodeObjectEx (X509_ASN_ENCODING, + PKCS_RSA_PRIVATE_KEY, + privateKeyInfo->PrivateKey.pbData, + (DWORD) privateKeyInfo->PrivateKey.cbData, + 0, + NULL, + raw_private, + &raw_private_len); + if (!success) { + goto cleanup; + } + + status = BCryptImportKeyPair ( + _algoRSA, + NULL, + LEGACY_RSAPRIVATE_BLOB, + &hKey, + raw_private, + raw_private_len, + 0); + if (!NT_SUCCESS (status)) { + goto cleanup; + } + + hash_value = calloc (1, SHA_256_HASH_LEN); + + if(!kms_sha256 (NULL, input, input_len, hash_value)) { + goto cleanup; + } + + padding_PKCS1.pszAlgId = BCRYPT_SHA256_ALGORITHM; + + status = + BCryptSignHash (hKey, + &padding_PKCS1, + hash_value, + SHA_256_HASH_LEN, + signature_out, + hash_length, + &hash_length, + BCRYPT_PAD_PKCS1); + if (!NT_SUCCESS (status)) { + goto cleanup; + } + + ret = true; + +cleanup: + BCryptDestroyKey(hKey); + free (blob_private); + free (raw_private); + free (hash_value); + + return ret; +} + #endif /* KMS_MESSAGE_ENABLE_CRYPTO_CNG */ diff --git a/src/kms/kms_decrypt_request.c b/src/kms/kms_decrypt_request.c index f1ca2827..25cbecad 100644 --- a/src/kms/kms_decrypt_request.c +++ b/src/kms/kms_decrypt_request.c @@ -59,7 +59,10 @@ kms_decrypt_request_new (const uint8_t *ciphertext_blob, payload = kms_request_str_new (); kms_request_str_appendf (payload, "{\"CiphertextBlob\": \"%s\"}", b64); - kms_request_append_payload (request, payload->str, payload->len); + if (!kms_request_append_payload (request, payload->str, payload->len)) { + KMS_ERROR (request, "Could not append payload"); + goto done; + } done: free (b64); diff --git a/src/kms/kms_encrypt_request.c b/src/kms/kms_encrypt_request.c index 24b064d9..3f922abc 100644 --- a/src/kms/kms_encrypt_request.c +++ b/src/kms/kms_encrypt_request.c @@ -60,7 +60,10 @@ kms_encrypt_request_new (const uint8_t *plaintext, payload = kms_request_str_new (); kms_request_str_appendf ( payload, "{\"Plaintext\": \"%s\", \"KeyId\": \"%s\"}", b64, key_id); - kms_request_append_payload (request, payload->str, payload->len); + if (!kms_request_append_payload (request, payload->str, payload->len)) { + KMS_ERROR (request, "Could not append payload"); + goto done; + } done: free (b64); diff --git a/src/kms/kms_endian_private.h b/src/kms/kms_endian_private.h new file mode 100644 index 00000000..02a72f16 --- /dev/null +++ b/src/kms/kms_endian_private.h @@ -0,0 +1,165 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This file is copied and modified from libbson's bson-endian.h. */ + +#ifndef KMS_ENDIAN_PRIVATE_H +#define KMS_ENDIAN_PRIVATE_H + +#include + +#include "kms_message/kms_message_defines.h" + +/* Define a fallback for __has_builtin for compatibility with non-clang compilers. */ +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif + +#if defined(__clang__) && __has_builtin(__builtin_bswap16) && \ + __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64) +#define KMS_UINT16_SWAP_LE_BE(v) __builtin_bswap16 (v) +#define KMS_UINT32_SWAP_LE_BE(v) __builtin_bswap32 (v) +#define KMS_UINT64_SWAP_LE_BE(v) __builtin_bswap64 (v) +#elif defined(__GNUC__) && (__GNUC__ >= 4) +#if __GNUC__ > 4 || (defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 3) +#define KMS_UINT32_SWAP_LE_BE(v) __builtin_bswap32 ((uint32_t) v) +#define KMS_UINT64_SWAP_LE_BE(v) __builtin_bswap64 ((uint64_t) v) +#endif +#if __GNUC__ > 4 || (defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 8) +#define KMS_UINT16_SWAP_LE_BE(v) __builtin_bswap16 ((uint32_t) v) +#endif +#endif + +#ifndef KMS_UINT16_SWAP_LE_BE +#define KMS_UINT16_SWAP_LE_BE(v) __kms_uint16_swap_slow ((uint16_t) v) +#endif + +#ifndef KMS_UINT32_SWAP_LE_BE +#define KMS_UINT32_SWAP_LE_BE(v) __kms_uint32_swap_slow ((uint32_t) v) +#endif + +#ifndef KMS_UINT64_SWAP_LE_BE +#define KMS_UINT64_SWAP_LE_BE(v) __kms_uint64_swap_slow ((uint64_t) v) +#endif + +#if defined(KMS_MESSAGE_LITTLE_ENDIAN) +#define KMS_UINT16_FROM_LE(v) ((uint16_t) v) +#define KMS_UINT16_TO_LE(v) ((uint16_t) v) +#define KMS_UINT16_FROM_BE(v) KMS_UINT16_SWAP_LE_BE (v) +#define KMS_UINT16_TO_BE(v) KMS_UINT16_SWAP_LE_BE (v) +#define KMS_UINT32_FROM_LE(v) ((uint32_t) v) +#define KMS_UINT32_TO_LE(v) ((uint32_t) v) +#define KMS_UINT32_FROM_BE(v) KMS_UINT32_SWAP_LE_BE (v) +#define KMS_UINT32_TO_BE(v) KMS_UINT32_SWAP_LE_BE (v) +#define KMS_UINT64_FROM_LE(v) ((uint64_t) v) +#define KMS_UINT64_TO_LE(v) ((uint64_t) v) +#define KMS_UINT64_FROM_BE(v) KMS_UINT64_SWAP_LE_BE (v) +#define KMS_UINT64_TO_BE(v) KMS_UINT64_SWAP_LE_BE (v) +#elif defined(KMS_MESSAGE_BIG_ENDIAN) +#define KMS_UINT16_FROM_LE(v) KMS_UINT16_SWAP_LE_BE (v) +#define KMS_UINT16_TO_LE(v) KMS_UINT16_SWAP_LE_BE (v) +#define KMS_UINT16_FROM_BE(v) ((uint16_t) v) +#define KMS_UINT16_TO_BE(v) ((uint16_t) v) +#define KMS_UINT32_FROM_LE(v) KMS_UINT32_SWAP_LE_BE (v) +#define KMS_UINT32_TO_LE(v) KMS_UINT32_SWAP_LE_BE (v) +#define KMS_UINT32_FROM_BE(v) ((uint32_t) v) +#define KMS_UINT32_TO_BE(v) ((uint32_t) v) +#define KMS_UINT64_FROM_LE(v) KMS_UINT64_SWAP_LE_BE (v) +#define KMS_UINT64_TO_LE(v) KMS_UINT64_SWAP_LE_BE (v) +#define KMS_UINT64_FROM_BE(v) ((uint64_t) v) +#define KMS_UINT64_TO_BE(v) ((uint64_t) v) +#else +#error "The endianness of target architecture is unknown." +#endif + +/* + *-------------------------------------------------------------------------- + * + * __kms_uint16_swap_slow -- + * + * Fallback endianness conversion for 16-bit integers. + * + * Returns: + * The endian swapped version. + * + * Side effects: + * None. + * + *-------------------------------------------------------------------------- + */ + +static KMS_MSG_INLINE uint16_t +__kms_uint16_swap_slow (uint16_t v) /* IN */ +{ + return (uint16_t) (((v & 0x00FF) << 8) | ((v & 0xFF00) >> 8)); +} + + +/* + *-------------------------------------------------------------------------- + * + * __kms_uint32_swap_slow -- + * + * Fallback endianness conversion for 32-bit integers. + * + * Returns: + * The endian swapped version. + * + * Side effects: + * None. + * + *-------------------------------------------------------------------------- + */ + +static KMS_MSG_INLINE uint32_t +__kms_uint32_swap_slow (uint32_t v) /* IN */ +{ + return ((v & 0x000000FFU) << 24) | ((v & 0x0000FF00U) << 8) | + ((v & 0x00FF0000U) >> 8) | ((v & 0xFF000000U) >> 24); +} + + +/* + *-------------------------------------------------------------------------- + * + * __kms_uint64_swap_slow -- + * + * Fallback endianness conversion for 64-bit integers. + * + * Returns: + * The endian swapped version. + * + * Side effects: + * None. + * + *-------------------------------------------------------------------------- + */ + +static KMS_MSG_INLINE uint64_t +__kms_uint64_swap_slow (uint64_t v) /* IN */ +{ + return ((v & 0x00000000000000FFULL) << 56) | + ((v & 0x000000000000FF00ULL) << 40) | + ((v & 0x0000000000FF0000ULL) << 24) | + ((v & 0x00000000FF000000ULL) << 8) | + ((v & 0x000000FF00000000ULL) >> 8) | + ((v & 0x0000FF0000000000ULL) >> 24) | + ((v & 0x00FF000000000000ULL) >> 40) | + ((v & 0xFF00000000000000ULL) >> 56); +} + + +#endif /* KMS_ENDIAN_PRIVATE_H */ diff --git a/src/kms/kms_gcp_request.c b/src/kms/kms_gcp_request.c new file mode 100644 index 00000000..564cacc6 --- /dev/null +++ b/src/kms/kms_gcp_request.c @@ -0,0 +1,286 @@ +/* + * Copyright 2020-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kms_message/kms_gcp_request.h" + +#include "kms_message/kms_b64.h" +#include "kms_message_private.h" +#include "kms_request_opt_private.h" + +/* Set a default expiration of 5 minutes for JSON Web Tokens (GCP allows up to + * one hour) */ +#define JWT_EXPIRATION_SECS 5 * 60 +#define SIGNATURE_LEN 256 + +kms_request_t * +kms_gcp_request_oauth_new (const char *host, + const char *email, + const char *audience, + const char *scope, + const char *private_key_data, + size_t private_key_len, + const kms_request_opt_t *opt) +{ + kms_request_t *req = NULL; + kms_request_str_t *str = NULL; + time_t issued_at; + /* base64 encoding of {"alg":"RS256","typ":"JWT"} */ + const char *jwt_header_b64url = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"; + char *jwt_claims_b64url = NULL; + char *jwt_header_and_claims_b64url = NULL; + uint8_t *jwt_signature = NULL; + char *jwt_signature_b64url = NULL; + char *jwt_assertion_b64url = NULL; + char *payload = NULL; + + req = kms_request_new ("POST", "/token", opt); + if (opt->provider != KMS_REQUEST_PROVIDER_GCP) { + KMS_ERROR (req, "Expected KMS request with provider type: GCP"); + goto done; + } + + if (kms_request_get_error (req)) { + goto done; + } + + /* Produce the signed JWT .. */ + issued_at = time (NULL); + str = kms_request_str_new (); + kms_request_str_appendf (str, + "{\"iss\": \"%s\", \"aud\": \"%s\", \"scope\": " + "\"%s\", \"iat\": %lu, \"exp\": %lu}", + email, + audience, + scope, + (unsigned long) issued_at, + (unsigned long) issued_at + JWT_EXPIRATION_SECS); + jwt_claims_b64url = + kms_message_raw_to_b64url ((const uint8_t *) str->str, str->len); + kms_request_str_destroy (str); + if (!jwt_claims_b64url) { + KMS_ERROR (req, "Failed to base64url encode JWT claims"); + goto done; + } + + str = kms_request_str_new (); + kms_request_str_appendf (str, "%s.%s", jwt_header_b64url, jwt_claims_b64url); + jwt_header_and_claims_b64url = kms_request_str_detach (str); + + /* Produce the signature of . */ + req->crypto.sign_rsaes_pkcs1_v1_5 = kms_sign_rsaes_pkcs1_v1_5; + if (opt->crypto.sign_rsaes_pkcs1_v1_5) { + req->crypto.sign_rsaes_pkcs1_v1_5 = opt->crypto.sign_rsaes_pkcs1_v1_5; + req->crypto.sign_ctx = opt->crypto.sign_ctx; + } + + jwt_signature = malloc (SIGNATURE_LEN); + if (!req->crypto.sign_rsaes_pkcs1_v1_5 ( + req->crypto.sign_ctx, + private_key_data, + private_key_len, + jwt_header_and_claims_b64url, + strlen (jwt_header_and_claims_b64url), + jwt_signature)) { + KMS_ERROR (req, "Failed to create GCP oauth request signature"); + goto done; + } + + jwt_signature_b64url = + kms_message_raw_to_b64url (jwt_signature, SIGNATURE_LEN); + if (!jwt_signature_b64url) { + KMS_ERROR (req, "Failed to base64url encode JWT signature"); + goto done; + } + str = kms_request_str_new (); + kms_request_str_appendf (str, + "%s.%s.%s", + jwt_header_b64url, + jwt_claims_b64url, + jwt_signature_b64url); + jwt_assertion_b64url = kms_request_str_detach (str); + + str = + kms_request_str_new_from_chars ("grant_type=urn%3Aietf%3Aparams%3Aoauth%" + "3Agrant-type%3Ajwt-bearer&assertion=", + -1); + kms_request_str_append_chars (str, jwt_assertion_b64url, -1); + payload = kms_request_str_detach (str); + + if (!kms_request_add_header_field ( + req, "Content-Type", "application/x-www-form-urlencoded")) { + goto done; + } + if (!kms_request_add_header_field (req, "Host", host)) { + goto done; + } + if (!kms_request_add_header_field (req, "Accept", "application/json")) { + goto done; + } + + if (!kms_request_append_payload (req, payload, strlen (payload))) { + goto done; + } + +done: + free (jwt_signature); + free (jwt_signature_b64url); + free (jwt_claims_b64url); + free (jwt_header_and_claims_b64url); + free (jwt_assertion_b64url); + free (payload); + return req; +} + +static kms_request_t * +_encrypt_decrypt_common (const char *encrypt_decrypt, + const char *host, + const char *access_token, + const char *project_id, + const char *location, + const char *key_ring_name, + const char *key_name, + const char *key_version, + const uint8_t *value, + size_t value_len, + const kms_request_opt_t *opt) +{ + char *path_and_query = NULL; + char *payload = NULL; + char *bearer_token_value = NULL; + char *value_base64 = NULL; + kms_request_t *req; + kms_request_str_t *str; + + str = kms_request_str_new (); + /* /v1/projects/{project-id}/locations/{location}/keyRings/{key-ring-name}/cryptoKeys/{key-name} + */ + kms_request_str_appendf ( + str, + "/v1/projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", + project_id, + location, + key_ring_name, + key_name); + if (key_version && strlen (key_version) > 0) { + kms_request_str_appendf (str, "/cryptoKeyVersions/%s", key_version); + } + kms_request_str_appendf (str, ":%s", encrypt_decrypt); + path_and_query = kms_request_str_detach (str); + + req = kms_request_new ("POST", path_and_query, opt); + + if (opt->provider != KMS_REQUEST_PROVIDER_GCP) { + KMS_ERROR (req, "Expected KMS request with provider type: GCP"); + goto done; + } + + if (kms_request_get_error (req)) { + goto done; + } + + value_base64 = kms_message_raw_to_b64 (value, value_len); + if (!value_base64) { + KMS_ERROR (req, "Could not bases64-encode plaintext"); + goto done; + } + + str = kms_request_str_new (); + if (0 == strcmp ("encrypt", encrypt_decrypt)) { + kms_request_str_appendf (str, "{\"plaintext\": \"%s\"}", value_base64); + } else { + kms_request_str_appendf (str, "{\"ciphertext\": \"%s\"}", value_base64); + } + + payload = kms_request_str_detach (str); + str = kms_request_str_new (); + kms_request_str_appendf (str, "Bearer %s", access_token); + bearer_token_value = kms_request_str_detach (str); + if (!kms_request_add_header_field ( + req, "Authorization", bearer_token_value)) { + goto done; + } + if (!kms_request_add_header_field ( + req, "Content-Type", "application/json")) { + goto done; + } + if (!kms_request_add_header_field (req, "Host", host)) { + goto done; + } + if (!kms_request_add_header_field (req, "Accept", "application/json")) { + goto done; + } + + if (!kms_request_append_payload (req, payload, strlen (payload))) { + goto done; + } + +done: + kms_request_free_string (path_and_query); + kms_request_free_string (payload); + kms_request_free_string (bearer_token_value); + kms_request_free_string (value_base64); + return req; +} + +kms_request_t * +kms_gcp_request_encrypt_new (const char *host, + const char *access_token, + const char *project_id, + const char *location, + const char *key_ring_name, + const char *key_name, + const char *key_version, + const uint8_t *plaintext, + size_t plaintext_len, + const kms_request_opt_t *opt) +{ + return _encrypt_decrypt_common ("encrypt", + host, + access_token, + project_id, + location, + key_ring_name, + key_name, + key_version, + plaintext, + plaintext_len, + opt); +} + +kms_request_t * +kms_gcp_request_decrypt_new (const char *host, + const char *access_token, + const char *project_id, + const char *location, + const char *key_ring_name, + const char *key_name, + const uint8_t *ciphertext, + size_t ciphertext_len, + const kms_request_opt_t *opt) +{ + return _encrypt_decrypt_common ("decrypt", + host, + access_token, + project_id, + location, + key_ring_name, + key_name, + NULL /* key_version */, + ciphertext, + ciphertext_len, + opt); +} \ No newline at end of file diff --git a/src/kms/kms_kmip_item_type_private.h b/src/kms/kms_kmip_item_type_private.h new file mode 100644 index 00000000..9f733909 --- /dev/null +++ b/src/kms/kms_kmip_item_type_private.h @@ -0,0 +1,59 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_KMIP_ITEM_TYPE_PRIVATE_H +#define KMS_KMIP_ITEM_TYPE_PRIVATE_H + +#include "kms_message/kms_message_defines.h" + +#define KMS_XMACRO \ + KMS_X (Structure, 0x01) \ + KMS_X (Integer, 0x02) \ + KMS_X (LongInteger, 0x03) \ + KMS_X (BigInteger, 0x04) \ + KMS_X (Enumeration, 0x05) \ + KMS_X (Boolean, 0x06) \ + KMS_X (TextString, 0x07) \ + KMS_X (ByteString, 0x08) \ + KMS_X (DateTime, 0x09) \ + KMS_X_LAST (Interval, 0x0A) + +/* Generate an enum with each item_type value. */ +#define KMS_X(ITEM_TYPE, VAL) KMIP_ITEM_TYPE_##ITEM_TYPE = VAL, +#define KMS_X_LAST(ITEM_TYPE, VAL) KMIP_ITEM_TYPE_##ITEM_TYPE = VAL +typedef enum { KMS_XMACRO } kmip_item_type_t; +#undef KMS_X +#undef KMS_X_LAST + +#define KMS_X(ITEM_TYPE, VAL) \ + case KMIP_ITEM_TYPE_##ITEM_TYPE: \ + return #ITEM_TYPE; +#define KMS_X_LAST KMS_X +static KMS_MSG_INLINE const char * +kmip_item_type_to_string (kmip_item_type_t item_type) +{ + switch (item_type) { + default: + return "Unknown KMIP item type"; + KMS_XMACRO + } +} +#undef KMS_X +#undef KMS_X_LAST + +#undef KMS_XMACRO + +#endif /* KMS_KMIP_ITEM_TYPE_PRIVATE_H */ diff --git a/src/kms/kms_kmip_reader_writer.c b/src/kms/kms_kmip_reader_writer.c new file mode 100644 index 00000000..08affaa9 --- /dev/null +++ b/src/kms/kms_kmip_reader_writer.c @@ -0,0 +1,502 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kms_kmip_reader_writer_private.h" + +#include "kms_endian_private.h" +#include "kms_request_str.h" + +#include + +#define MAX_KMIP_WRITER_POSITIONS 10 + +/* KMIP encodes signed integers with two's complement. + * Parsing functions read Integer / LongInteger as int32_t / int64_t by + * reinterpreting byte representation. + * Ensure that platform represents integers in two's complement. + * See: https://stackoverflow.com/a/64843863/774658 */ +#if (-1 & 3) != 3 +#error Error: Twos complement integer representation is required. +#endif + +struct _kmip_writer_t { + kms_request_str_t *buffer; + + size_t positions[MAX_KMIP_WRITER_POSITIONS]; + size_t cur_pos; +}; + +kmip_writer_t * +kmip_writer_new (void) +{ + kmip_writer_t *writer = calloc (1, sizeof (kmip_writer_t)); + writer->buffer = kms_request_str_new (); + return writer; +} + +void +kmip_writer_destroy (kmip_writer_t *writer) +{ + kms_request_str_destroy (writer->buffer); + free (writer); +} + +void +kmip_writer_write_u8 (kmip_writer_t *writer, uint8_t value) +{ + char *c = (char *) &value; + + kms_request_str_append_chars (writer->buffer, c, 1); +} + +void +kmip_writer_write_u16 (kmip_writer_t *writer, uint16_t value) +{ + uint16_t v = KMS_UINT16_TO_BE (value); + char *c = (char *) &v; + + kms_request_str_append_chars (writer->buffer, c, 2); +} + +void +kmip_writer_write_u32 (kmip_writer_t *writer, uint32_t value) +{ + uint32_t v = KMS_UINT32_TO_BE (value); + char *c = (char *) &v; + + kms_request_str_append_chars (writer->buffer, c, 4); +} + +void +kmip_writer_write_u64 (kmip_writer_t *writer, uint64_t value) +{ + uint64_t v = KMS_UINT64_TO_BE (value); + char *c = (char *) &v; + + kms_request_str_append_chars (writer->buffer, c, 8); +} + +void +kmip_writer_write_tag_enum (kmip_writer_t *writer, kmip_tag_type_t tag) +{ + /* The 0x42 prefix is for tags built into the protocol. */ + /* The 0x54 prefix is for extension tags. */ + kmip_writer_write_u8 (writer, 0x42); + kmip_writer_write_u16 (writer, (uint16_t) tag); +} + +static size_t +compute_padded_length (size_t len) +{ + if (len % 8 == 0) { + return len; + } + + size_t padding = 8 - (len % 8); + return len + padding; +} + +void +kmip_writer_write_string (kmip_writer_t *writer, kmip_tag_type_t tag, const char *str, size_t len) +{ + kmip_writer_write_tag_enum (writer, tag); + kmip_writer_write_u8 (writer, KMIP_ITEM_TYPE_TextString); + kmip_writer_write_u32 (writer, (uint32_t) len); + + size_t i; + for (i = 0; i < len; i++) { + kmip_writer_write_u8 (writer, (uint8_t) str[i]); + } + + size_t padded_length = compute_padded_length (len); + for (i = 0; i < padded_length - len; i++) { + kmip_writer_write_u8 (writer, 0); + } +} + +void +kmip_writer_write_bytes (kmip_writer_t *writer, kmip_tag_type_t tag, const char *str, size_t len) +{ + kmip_writer_write_tag_enum (writer, tag); + + kmip_writer_write_u8 (writer, KMIP_ITEM_TYPE_ByteString); + kmip_writer_write_u32 (writer, (uint32_t) len); + + size_t i; + for (i = 0; i < len; i++) { + kmip_writer_write_u8 (writer, (uint8_t) str[i]); + } + + size_t padded_length = compute_padded_length (len); + for (i = 0; i < padded_length - len; i++) { + kmip_writer_write_u8 (writer, 0); + } +} + +void +kmip_writer_write_integer (kmip_writer_t *writer, kmip_tag_type_t tag, int32_t value) +{ + kmip_writer_write_tag_enum (writer, tag); + kmip_writer_write_u8 (writer, KMIP_ITEM_TYPE_Integer); + kmip_writer_write_u32 (writer, 4); + KMS_ASSERT (value >= 0); + kmip_writer_write_u32 (writer, (uint32_t) value); + kmip_writer_write_u32 (writer, 0); +} + +void +kmip_writer_write_long_integer (kmip_writer_t *writer, kmip_tag_type_t tag, int64_t value) +{ + kmip_writer_write_tag_enum (writer, tag); + kmip_writer_write_u8 (writer, KMIP_ITEM_TYPE_LongInteger); + kmip_writer_write_u32 (writer, 8); + KMS_ASSERT (value >= 0); + kmip_writer_write_u64 (writer, (uint64_t) value); +} + +void +kmip_writer_write_enumeration (kmip_writer_t *writer, kmip_tag_type_t tag, int32_t value) +{ + kmip_writer_write_tag_enum (writer, tag); + kmip_writer_write_u8 (writer, KMIP_ITEM_TYPE_Enumeration); + kmip_writer_write_u32 (writer, 4); + KMS_ASSERT (value >= 0); + kmip_writer_write_u32 (writer, (uint32_t) value); + kmip_writer_write_u32 (writer, 0); +} + +void +kmip_writer_write_datetime (kmip_writer_t *writer, kmip_tag_type_t tag, int64_t value) +{ + kmip_writer_write_tag_enum (writer, tag); + kmip_writer_write_u8 (writer, KMIP_ITEM_TYPE_DateTime); + kmip_writer_write_u32 (writer, 8); + KMS_ASSERT (value >= 0); + kmip_writer_write_u64 (writer, (uint64_t) value); +} + +void +kmip_writer_begin_struct (kmip_writer_t *writer, kmip_tag_type_t tag) +{ + kmip_writer_write_tag_enum (writer, tag); + kmip_writer_write_u8 (writer, KMIP_ITEM_TYPE_Structure); + + size_t pos = writer->buffer->len; + + kmip_writer_write_u32 (writer, 0); + KMS_ASSERT(writer->cur_pos < MAX_KMIP_WRITER_POSITIONS); + writer->cur_pos++; + writer->positions[writer->cur_pos] = pos; +} + +void +kmip_writer_close_struct (kmip_writer_t *writer) +{ + size_t current_pos = writer->buffer->len; + KMS_ASSERT(writer->cur_pos > 0); + size_t start_pos = writer->positions[writer->cur_pos]; + writer->cur_pos--; + /* offset by 4 */ + uint32_t len = (uint32_t) (current_pos - start_pos - 4); + + uint32_t v = KMS_UINT32_TO_BE (len); + char *c = (char *) &v; + memcpy (writer->buffer->str + start_pos, c, 4); +} + +const uint8_t * +kmip_writer_get_buffer (kmip_writer_t *writer, size_t* len) { + *len = writer->buffer->len; + return (const uint8_t*) writer->buffer->str; +} + +struct _kmip_reader_t { + uint8_t *ptr; + size_t pos; + size_t len; +}; + +kmip_reader_t * +kmip_reader_new (uint8_t *ptr, size_t len) +{ + kmip_reader_t *reader = calloc (1, sizeof (kmip_reader_t)); + reader->ptr = ptr; + reader->len = len; + return reader; +} + +void +kmip_reader_destroy (kmip_reader_t *reader) +{ + free (reader); +} + +bool +kmip_reader_in_place (kmip_reader_t *reader, + size_t pos, + size_t len, + kmip_reader_t *out_reader) +{ + /* Everything should be padding to 8 byte boundaries. */ + len = compute_padded_length (len); + if ((pos + len) > reader->len) { + return false; + } + + memset (out_reader, 0, sizeof (kmip_reader_t)); + out_reader->ptr = reader->ptr + reader->pos; + out_reader->len = len; + return true; +} + +bool +kmip_reader_has_data (kmip_reader_t *reader) +{ + return reader->pos < reader->len; +} + +#define CHECK_REMAINING_BUFFER_AND_RET(read_size) \ + if ((reader->pos + (read_size)) > reader->len) { \ + return false; \ + } + +bool +kmip_reader_read_u8 (kmip_reader_t *reader, uint8_t *value) +{ + CHECK_REMAINING_BUFFER_AND_RET (sizeof (uint8_t)); + + *value = *(reader->ptr + reader->pos); + reader->pos += sizeof (uint8_t); + + return true; +} + +bool +kmip_reader_read_u16 (kmip_reader_t *reader, uint16_t *value) +{ + CHECK_REMAINING_BUFFER_AND_RET (sizeof (uint16_t)); + + uint16_t temp; + memcpy (&temp, reader->ptr + reader->pos, sizeof (uint16_t)); + *value = KMS_UINT16_FROM_BE (temp); + reader->pos += sizeof (uint16_t); + + return true; +} + +bool +kmip_reader_read_u32 (kmip_reader_t *reader, uint32_t *value) +{ + CHECK_REMAINING_BUFFER_AND_RET (sizeof (uint32_t)); + + uint32_t temp; + memcpy (&temp, reader->ptr + reader->pos, sizeof (uint32_t)); + *value = KMS_UINT32_FROM_BE (temp); + reader->pos += sizeof (uint32_t); + + return true; +} + +bool +kmip_reader_read_u64 (kmip_reader_t *reader, uint64_t *value) +{ + CHECK_REMAINING_BUFFER_AND_RET (sizeof (uint64_t)); + + uint64_t temp; + memcpy (&temp, reader->ptr + reader->pos, sizeof (uint64_t)); + *value = KMS_UINT64_FROM_BE (temp); + reader->pos += sizeof (uint64_t); + + return true; +} + +bool +kmip_reader_read_bytes (kmip_reader_t *reader, uint8_t **ptr, size_t length) +{ + size_t advance_length = compute_padded_length (length); + CHECK_REMAINING_BUFFER_AND_RET (advance_length); + + *ptr = reader->ptr + reader->pos; + reader->pos += advance_length; + + return true; +} + +#define CHECK_AND_RET(x) \ + if (!(x)) { \ + return false; \ + } + +bool +kmip_reader_read_tag (kmip_reader_t *reader, kmip_tag_type_t *tag) +{ + uint8_t tag_first; + + CHECK_AND_RET (kmip_reader_read_u8 (reader, &tag_first)); + + if (tag_first != 0x42) { + return false; + } + + uint16_t tag_second; + CHECK_AND_RET (kmip_reader_read_u16 (reader, &tag_second)); + + *tag = (kmip_tag_type_t) (0x420000 + tag_second); + return true; +} + +bool +kmip_reader_read_length (kmip_reader_t *reader, uint32_t *length) +{ + return kmip_reader_read_u32 (reader, length); +} + +bool +kmip_reader_read_type (kmip_reader_t *reader, kmip_item_type_t *type) +{ + uint8_t u8; + CHECK_AND_RET (kmip_reader_read_u8 (reader, &u8)); + *type = (kmip_item_type_t) u8; + return true; +} + +bool +kmip_reader_read_enumeration (kmip_reader_t *reader, uint32_t *enum_value) +{ + CHECK_AND_RET (kmip_reader_read_u32 (reader, enum_value)); + + /* Skip 4 bytes because enums are padded. */ + uint32_t ignored; + + return kmip_reader_read_u32 (reader, &ignored); +} + +bool +kmip_reader_read_integer (kmip_reader_t *reader, int32_t *value) +{ + CHECK_AND_RET (kmip_reader_read_u32 (reader, (uint32_t*) value)); + + /* Skip 4 bytes because integers are padded. */ + uint32_t ignored; + + return kmip_reader_read_u32 (reader, &ignored); +} + +bool +kmip_reader_read_long_integer (kmip_reader_t *reader, int64_t *value) +{ + return kmip_reader_read_u64 (reader, (uint64_t*) value); +} + +bool +kmip_reader_read_string (kmip_reader_t *reader, uint8_t **ptr, size_t length) +{ + return kmip_reader_read_bytes (reader, ptr, length); +} + +bool +kmip_reader_find (kmip_reader_t *reader, + kmip_tag_type_t search_tag, + kmip_item_type_t type, + size_t *pos, + size_t *length) +{ + reader->pos = 0; + + while (kmip_reader_has_data (reader)) { + kmip_tag_type_t read_tag; + CHECK_AND_RET (kmip_reader_read_tag (reader, &read_tag)); + + kmip_item_type_t read_type; + CHECK_AND_RET (kmip_reader_read_type (reader, &read_type)); + + uint32_t read_length; + CHECK_AND_RET (kmip_reader_read_length (reader, &read_length)); + + + if (read_tag == search_tag && read_type == type) { + *pos = reader->pos; + *length = read_length; + return true; + } + + size_t advance_length = read_length; + advance_length = compute_padded_length (advance_length); + + CHECK_REMAINING_BUFFER_AND_RET (advance_length); + + /* Skip to the next type. */ + reader->pos += advance_length; + } + + return false; +} + +bool +kmip_reader_find_and_recurse (kmip_reader_t *reader, kmip_tag_type_t tag) +{ + size_t pos; + size_t length; + + if (!kmip_reader_find (reader, tag, KMIP_ITEM_TYPE_Structure, &pos, &length)) { + return false; + } + + reader->pos = 0; + reader->ptr = reader->ptr + pos; + reader->len = length; + return true; +} + +bool +kmip_reader_find_and_read_enum (kmip_reader_t *reader, + kmip_tag_type_t tag, + uint32_t *value) +{ + size_t pos; + size_t length; + + if (!kmip_reader_find (reader, tag, KMIP_ITEM_TYPE_Enumeration, &pos, &length)) { + return false; + } + + kmip_reader_t temp_reader; + if (!kmip_reader_in_place (reader, pos, length, &temp_reader)) { + return false; + } + + return kmip_reader_read_enumeration (&temp_reader, value); +} + +bool +kmip_reader_find_and_read_bytes (kmip_reader_t *reader, + kmip_tag_type_t tag, + uint8_t **out_ptr, + size_t *out_len) +{ + size_t pos; + + if (!kmip_reader_find (reader, tag, KMIP_ITEM_TYPE_ByteString, &pos, out_len)) { + return false; + } + + kmip_reader_t temp_reader; + if (!kmip_reader_in_place (reader, pos, *out_len, &temp_reader)) { + return false; + } + + return kmip_reader_read_bytes (&temp_reader, out_ptr, *out_len); +} diff --git a/src/kms/kms_kmip_reader_writer_private.h b/src/kms/kms_kmip_reader_writer_private.h new file mode 100644 index 00000000..314bf394 --- /dev/null +++ b/src/kms/kms_kmip_reader_writer_private.h @@ -0,0 +1,150 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_KMIP_READER_WRITER_PRIVATE_H +#define KMS_KMIP_READER_WRITER_PRIVATE_H + +#include "kms_kmip_item_type_private.h" +#include "kms_kmip_tag_type_private.h" +#include "kms_message_private.h" + +#include + +typedef struct _kmip_writer_t kmip_writer_t; + +kmip_writer_t * kmip_writer_new (void); + +void kmip_writer_destroy (kmip_writer_t *writer); + +void +kmip_writer_write_u8 (kmip_writer_t *writer, uint8_t value); + +void +kmip_writer_write_u16 (kmip_writer_t *writer, uint16_t value); + +void +kmip_writer_write_u32 (kmip_writer_t *writer, uint32_t value); + +void +kmip_writer_write_u64 (kmip_writer_t *writer, uint64_t value); + +void +kmip_writer_write_tag_enum (kmip_writer_t *writer, kmip_tag_type_t tag); + +void +kmip_writer_write_string (kmip_writer_t *writer, kmip_tag_type_t tag, const char *str, size_t len); + +void +kmip_writer_write_bytes (kmip_writer_t *writer, kmip_tag_type_t tag, const char *str, size_t len); + +void +kmip_writer_write_integer (kmip_writer_t *writer, kmip_tag_type_t tag, int32_t value); + +void +kmip_writer_write_long_integer (kmip_writer_t *writer, kmip_tag_type_t tag, int64_t value); + +void +kmip_writer_write_enumeration (kmip_writer_t *writer, kmip_tag_type_t tag, int32_t value); + +void +kmip_writer_write_datetime (kmip_writer_t *writer, kmip_tag_type_t tag, int64_t value); + +void +kmip_writer_begin_struct (kmip_writer_t *writer, kmip_tag_type_t tag); + +void +kmip_writer_close_struct (kmip_writer_t *writer); + +const uint8_t * +kmip_writer_get_buffer (kmip_writer_t *writer, size_t* len); + +typedef struct _kmip_reader_t kmip_reader_t; + +kmip_reader_t * +kmip_reader_new (uint8_t *ptr, size_t len); + +void +kmip_reader_destroy (kmip_reader_t *reader); + +bool +kmip_reader_in_place (kmip_reader_t *reader, + size_t pos, + size_t len, + kmip_reader_t *out_reader); + +bool +kmip_reader_has_data (kmip_reader_t *reader); + +bool +kmip_reader_read_u8 (kmip_reader_t *reader, uint8_t *value); + +bool +kmip_reader_read_u16 (kmip_reader_t *reader, uint16_t *value); + +bool +kmip_reader_read_u32 (kmip_reader_t *reader, uint32_t *value); + +bool +kmip_reader_read_u64 (kmip_reader_t *reader, uint64_t *value); + +bool +kmip_reader_read_tag (kmip_reader_t *reader, kmip_tag_type_t *tag); + +bool +kmip_reader_read_length (kmip_reader_t *reader, uint32_t *length); + +bool +kmip_reader_read_type (kmip_reader_t *reader, kmip_item_type_t *type); + +bool +kmip_reader_read_enumeration (kmip_reader_t *reader, uint32_t *enum_value); + +bool +kmip_reader_read_integer (kmip_reader_t *reader, int32_t *value); + +bool +kmip_reader_read_long_integer (kmip_reader_t *reader, int64_t *value); + +bool +kmip_reader_read_bytes (kmip_reader_t *reader, uint8_t **ptr, size_t length); + +bool +kmip_reader_read_string (kmip_reader_t *reader, uint8_t **ptr, size_t length); + +/* kmip_reader_find does not descend structures. + * To find and descend into a structure use kmip_reader_find_and_recurse. */ +bool +kmip_reader_find (kmip_reader_t *reader, + kmip_tag_type_t search_tag, + kmip_item_type_t type, + size_t *pos, + size_t *length); + +bool +kmip_reader_find_and_recurse (kmip_reader_t *reader, kmip_tag_type_t tag); + +bool +kmip_reader_find_and_read_enum (kmip_reader_t *reader, + kmip_tag_type_t tag, + uint32_t *value); + +bool +kmip_reader_find_and_read_bytes (kmip_reader_t *reader, + kmip_tag_type_t tag, + uint8_t **out_ptr, + size_t *out_len); + +#endif /* KMS_KMIP_READER_WRITER_PRIVATE_H */ diff --git a/src/kms/kms_kmip_request.c b/src/kms/kms_kmip_request.c new file mode 100644 index 00000000..c59bff7c --- /dev/null +++ b/src/kms/kms_kmip_request.c @@ -0,0 +1,256 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kms_message/kms_kmip_request.h" + +#include "kms_message_private.h" +#include "kms_kmip_reader_writer_private.h" + +#include +#include + +static void +copy_writer_buffer (kms_request_t *req, kmip_writer_t *writer) +{ + const uint8_t *buf; + size_t buflen; + + buf = kmip_writer_get_buffer (writer, &buflen); + req->kmip.data = malloc (buflen); + memcpy (req->kmip.data, buf, buflen); + req->kmip.len = (uint32_t) buflen; +} + +kms_request_t * +kms_kmip_request_register_secretdata_new (void *reserved, + const uint8_t *data, + size_t len) +{ + /* + Create a KMIP Register request with a 96 byte SecretData of this form: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */ + + kmip_writer_t *writer; + kms_request_t *req; + + req = calloc (1, sizeof (kms_request_t)); + req->provider = KMS_REQUEST_PROVIDER_KMIP; + + if (len != KMS_KMIP_REQUEST_SECRETDATA_LENGTH) { + KMS_ERROR (req, + "expected SecretData length of %d, got %" PRIu32, + KMS_KMIP_REQUEST_SECRETDATA_LENGTH, + len); + return req; + } + + writer = kmip_writer_new (); + kmip_writer_begin_struct (writer, KMIP_TAG_RequestMessage); + + kmip_writer_begin_struct (writer, KMIP_TAG_RequestHeader); + kmip_writer_begin_struct (writer, KMIP_TAG_ProtocolVersion); + kmip_writer_write_integer (writer, KMIP_TAG_ProtocolVersionMajor, 1); + kmip_writer_write_integer (writer, KMIP_TAG_ProtocolVersionMinor, 0); + kmip_writer_close_struct (writer); /* KMIP_TAG_ProtocolVersion */ + kmip_writer_write_integer (writer, KMIP_TAG_BatchCount, 1); + kmip_writer_close_struct (writer); /* KMIP_TAG_RequestHeader */ + + kmip_writer_begin_struct (writer, KMIP_TAG_BatchItem); + /* 0x03 == Register */ + kmip_writer_write_enumeration (writer, KMIP_TAG_Operation, 0x03); + kmip_writer_begin_struct (writer, KMIP_TAG_RequestPayload); + /* 0x07 == SecretData */ + kmip_writer_write_enumeration (writer, KMIP_TAG_ObjectType, 0x07); + kmip_writer_begin_struct (writer, KMIP_TAG_TemplateAttribute); + // Add required Cryptographic Usage Mask attribute. + { + kmip_writer_begin_struct (writer, KMIP_TAG_Attribute); + const char *cryptographicUsageMaskStr = "Cryptographic Usage Mask"; + kmip_writer_write_string (writer, + KMIP_TAG_AttributeName, + cryptographicUsageMaskStr, + strlen (cryptographicUsageMaskStr)); + // Use 0 because the Secret Data object is not used in cryptographic + // operations on the KMIP server. + kmip_writer_write_integer (writer, KMIP_TAG_AttributeValue, 0); + kmip_writer_close_struct (writer); + } + kmip_writer_close_struct (writer); /* KMIP_TAG_TemplateAttribute */ + kmip_writer_begin_struct (writer, KMIP_TAG_SecretData); + /* 0x02 = Seed */ + kmip_writer_write_enumeration (writer, KMIP_TAG_SecretDataType, 0x02); + kmip_writer_begin_struct (writer, KMIP_TAG_KeyBlock); + /* 0x02 = Opaque */ + kmip_writer_write_enumeration (writer, KMIP_TAG_KeyFormatType, 0x02); + kmip_writer_begin_struct (writer, KMIP_TAG_KeyValue); + kmip_writer_write_bytes ( + writer, KMIP_TAG_KeyMaterial, (const char *) data, len); + kmip_writer_close_struct (writer); /* KMIP_TAG_KeyValue */ + kmip_writer_close_struct (writer); /* KMIP_TAG_KeyBlock */ + kmip_writer_close_struct (writer); /* KMIP_TAG_SecretData */ + kmip_writer_close_struct (writer); /* KMIP_TAG_RequestPayload */ + kmip_writer_close_struct (writer); /* KMIP_TAG_BatchItem */ + kmip_writer_close_struct (writer); /* KMIP_TAG_RequestMessage */ + + copy_writer_buffer (req, writer); + kmip_writer_destroy (writer); + return req; +} + +kms_request_t * +kms_kmip_request_activate_new (void *reserved, const char *unique_identifer) +{ + /* + Create a KMIP Activate request of this form: + + + + + + + + + + + + + + + + */ + + kmip_writer_t *writer; + kms_request_t *req; + + req = calloc (1, sizeof (kms_request_t)); + req->provider = KMS_REQUEST_PROVIDER_KMIP; + + writer = kmip_writer_new (); + kmip_writer_begin_struct (writer, KMIP_TAG_RequestMessage); + + kmip_writer_begin_struct (writer, KMIP_TAG_RequestHeader); + kmip_writer_begin_struct (writer, KMIP_TAG_ProtocolVersion); + kmip_writer_write_integer (writer, KMIP_TAG_ProtocolVersionMajor, 1); + kmip_writer_write_integer (writer, KMIP_TAG_ProtocolVersionMinor, 0); + kmip_writer_close_struct (writer); /* KMIP_TAG_ProtocolVersion */ + kmip_writer_write_integer (writer, KMIP_TAG_BatchCount, 1); + kmip_writer_close_struct (writer); /* KMIP_TAG_RequestHeader */ + + kmip_writer_begin_struct (writer, KMIP_TAG_BatchItem); + /* 0x0A == Get */ + kmip_writer_write_enumeration (writer, KMIP_TAG_Operation, 0x12); + kmip_writer_begin_struct (writer, KMIP_TAG_RequestPayload); + kmip_writer_write_string (writer, + KMIP_TAG_UniqueIdentifier, + unique_identifer, + strlen (unique_identifer)); + kmip_writer_close_struct (writer); /* KMIP_TAG_RequestPayload */ + kmip_writer_close_struct (writer); /* KMIP_TAG_BatchItem */ + kmip_writer_close_struct (writer); /* KMIP_TAG_RequestMessage */ + + copy_writer_buffer (req, writer); + kmip_writer_destroy (writer); + return req; +} + +kms_request_t * +kms_kmip_request_get_new (void *reserved, const char *unique_identifer) +{ + /* + Create a KMIP Get request of this form: + + + + + + + + + + + + + + + + */ + + kmip_writer_t *writer; + kms_request_t *req; + + req = calloc (1, sizeof (kms_request_t)); + req->provider = KMS_REQUEST_PROVIDER_KMIP; + + writer = kmip_writer_new (); + kmip_writer_begin_struct (writer, KMIP_TAG_RequestMessage); + + kmip_writer_begin_struct (writer, KMIP_TAG_RequestHeader); + kmip_writer_begin_struct (writer, KMIP_TAG_ProtocolVersion); + kmip_writer_write_integer (writer, KMIP_TAG_ProtocolVersionMajor, 1); + kmip_writer_write_integer (writer, KMIP_TAG_ProtocolVersionMinor, 0); + kmip_writer_close_struct (writer); /* KMIP_TAG_ProtocolVersion */ + kmip_writer_write_integer (writer, KMIP_TAG_BatchCount, 1); + kmip_writer_close_struct (writer); /* KMIP_TAG_RequestHeader */ + + kmip_writer_begin_struct (writer, KMIP_TAG_BatchItem); + /* 0x0A == Get */ + kmip_writer_write_enumeration (writer, KMIP_TAG_Operation, 0x0A); + kmip_writer_begin_struct (writer, KMIP_TAG_RequestPayload); + kmip_writer_write_string (writer, + KMIP_TAG_UniqueIdentifier, + unique_identifer, + strlen (unique_identifer)); + /* 0x01 = Raw */ + kmip_writer_close_struct (writer); /* KMIP_TAG_RequestPayload */ + kmip_writer_close_struct (writer); /* KMIP_TAG_BatchItem */ + kmip_writer_close_struct (writer); /* KMIP_TAG_RequestMessage */ + + /* Copy the KMIP writer buffer to a KMIP request. */ + copy_writer_buffer (req, writer); + kmip_writer_destroy (writer); + return req; +} diff --git a/src/kms/kms_kmip_response.c b/src/kms/kms_kmip_response.c new file mode 100644 index 00000000..b4dc2c6f --- /dev/null +++ b/src/kms/kms_kmip_response.c @@ -0,0 +1,323 @@ +#include "kms_message/kms_kmip_response.h" + +#include "kms_message_private.h" +#include "kms_kmip_reader_writer_private.h" +#include "kms_kmip_result_reason_private.h" +#include "kms_kmip_result_status_private.h" + +#include +#include +#include /* CHAR_BIT */ + +static bool +check_and_require_kmip (kms_response_t *res) +{ + if (res->provider != KMS_REQUEST_PROVIDER_KMIP) { + KMS_ERROR (res, "Function requires KMIP request"); + return false; + } + return true; +} + +/* +Example of an error message: + + + + + + + + + + + + + + + + +*/ +static bool +kms_kmip_response_ok (kms_response_t *res) +{ + kmip_reader_t *reader = NULL; + size_t pos; + size_t len; + uint32_t result_status; + uint32_t result_reason = 0; + const char *result_message = ""; + uint32_t result_message_len = 0; + bool ok = false; + + reader = kmip_reader_new (res->kmip.data, res->kmip.len); + + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_ResponseMessage)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_ResponseMessage)); + goto fail; + } + + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_BatchItem)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_BatchItem)); + goto fail; + } + + /* Look for optional Result Reason. */ + if (kmip_reader_find (reader, + KMIP_TAG_ResultReason, + KMIP_ITEM_TYPE_Enumeration, + &pos, + &len)) { + if (!kmip_reader_read_enumeration (reader, &result_reason)) { + KMS_ERROR (res, "unable to read result reason value"); + goto fail; + } + } + + /* Look for optional Result Message. */ + if (kmip_reader_find (reader, + KMIP_TAG_ResultMessage, + KMIP_ITEM_TYPE_TextString, + &pos, + &len)) { + if (!kmip_reader_read_string ( + reader, (uint8_t **) &result_message, len)) { + KMS_ERROR (res, "unable to read result message value"); + goto fail; + } + result_message_len = (uint32_t) len; + } + + /* Look for required Result Status. */ + if (!kmip_reader_find (reader, + KMIP_TAG_ResultStatus, + KMIP_ITEM_TYPE_Enumeration, + &pos, + &len)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_ResultStatus)); + goto fail; + } + + if (!kmip_reader_read_enumeration (reader, &result_status)) { + KMS_ERROR (res, "unable to read result status value"); + goto fail; + } + + if (result_status != KMIP_RESULT_STATUS_OperationSuccess) { + KMS_ERROR (res, + "KMIP response error. Result Status (%" PRIu32 + "): %s. Result Reason (%" PRIu32 "): %s. Result Message: %.*s", + result_status, + kmip_result_status_to_string (result_status), + result_reason, + kmip_result_reason_to_string (result_reason), + result_message_len, + result_message); + goto fail; + } + + ok = true; +fail: + kmip_reader_destroy (reader); + return ok; +} + +/* +Example of a successful response to a Register request: + + + + + + + + + + + + + + + + + + */ +char * +kms_kmip_response_get_unique_identifier (kms_response_t *res) +{ + kmip_reader_t *reader = NULL; + size_t pos; + size_t len; + char *uid = NULL; + kms_request_str_t *nullterminated = NULL; + + if (!check_and_require_kmip (res)) { + goto fail; + } + + if (!kms_kmip_response_ok (res)) { + goto fail; + } + + reader = kmip_reader_new (res->kmip.data, res->kmip.len); + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_ResponseMessage)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_ResponseMessage)); + goto fail; + } + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_BatchItem)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_BatchItem)); + goto fail; + } + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_ResponsePayload)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_ResponsePayload)); + goto fail; + } + if (!kmip_reader_find (reader, + KMIP_TAG_UniqueIdentifier, + KMIP_ITEM_TYPE_TextString, + &pos, + &len)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_UniqueIdentifier)); + goto fail; + } + + if (!kmip_reader_read_string (reader, (uint8_t **) &uid, len)) { + KMS_ERROR (res, "unable to read unique identifier"); + goto fail; + } + + KMS_ASSERT (len <= SSIZE_MAX); + nullterminated = kms_request_str_new_from_chars (uid, (ssize_t) len); + +fail: + kmip_reader_destroy (reader); + return kms_request_str_detach (nullterminated); +} + +/* +Example of a successful response to a Get request: + + + + + + + + + + + + + + + + + + + + + + + + + + + +*/ +uint8_t * +kms_kmip_response_get_secretdata (kms_response_t *res, size_t *secretdatalen) +{ + kmip_reader_t *reader = NULL; + size_t pos; + size_t len; + uint8_t *secretdata = NULL; + uint8_t *tmp; + + if (!check_and_require_kmip (res)) { + goto fail; + } + + if (!kms_kmip_response_ok (res)) { + goto fail; + } + + reader = kmip_reader_new (res->kmip.data, res->kmip.len); + + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_ResponseMessage)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_ResponseMessage)); + goto fail; + } + + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_BatchItem)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_BatchItem)); + goto fail; + } + + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_ResponsePayload)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_ResponsePayload)); + goto fail; + } + + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_SecretData)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_SecretData)); + goto fail; + } + + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_KeyBlock)) { + KMS_ERROR ( + res, "unable to find tag: %s", kmip_tag_to_string (KMIP_TAG_KeyBlock)); + goto fail; + } + + if (!kmip_reader_find_and_recurse (reader, KMIP_TAG_KeyValue)) { + KMS_ERROR ( + res, "unable to find tag: %s", kmip_tag_to_string (KMIP_TAG_KeyValue)); + goto fail; + } + + if (!kmip_reader_find (reader, + KMIP_TAG_KeyMaterial, + KMIP_ITEM_TYPE_ByteString, + &pos, + &len)) { + KMS_ERROR (res, + "unable to find tag: %s", + kmip_tag_to_string (KMIP_TAG_KeyMaterial)); + goto fail; + } + + if (!kmip_reader_read_bytes (reader, &tmp, len)) { + KMS_ERROR (res, "unable to read secretdata bytes"); + goto fail; + } + secretdata = malloc (len); + memcpy (secretdata, tmp, len); + *secretdatalen = len; + +fail: + kmip_reader_destroy (reader); + return secretdata; +} diff --git a/src/kms/kms_kmip_response_parser.c b/src/kms/kms_kmip_response_parser.c new file mode 100644 index 00000000..d5364d29 --- /dev/null +++ b/src/kms/kms_kmip_response_parser.c @@ -0,0 +1,148 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kms_message/kms_kmip_response_parser.h" + +#include "kms_endian_private.h" +#include "kms_kmip_response_parser_private.h" +#include "kms_message_private.h" +#include "kms_request_str.h" + +struct _kms_kmip_response_parser_t { + uint32_t first_len; + uint32_t bytes_fed; + kms_request_str_t *buf; + bool failed; + char error[512]; +}; + +/* FIRST_LENGTH_OFFSET is the offset of the first Length in a TTLV sequence. The + * sequence is: Tag (3 bytes), Type (1 byte), Length (4 bytes), Value (Length + * bytes). */ +static const uint32_t FIRST_LENGTH_OFFSET = 4; + +/* _parser_destroy destroys the fields of parser, but not the parser itself. */ +static void +_parser_destroy (kms_kmip_response_parser_t *parser) +{ + kms_request_str_destroy (parser->buf); +} + +/* _parser_init initializes the members of parser. */ +static void +_parser_init (kms_kmip_response_parser_t *parser) +{ + memset (parser, 0, sizeof (*parser)); + parser->buf = kms_request_str_new (); +} + +kms_response_parser_t * +kms_kmip_response_parser_new (void *reserved) +{ + kms_response_parser_t *parser = kms_response_parser_new (); + + parser->kmip = malloc (sizeof (kms_kmip_response_parser_t)); + _parser_init (parser->kmip); + + return parser; +} + +int32_t +kms_kmip_response_parser_wants_bytes (const kms_kmip_response_parser_t *parser, + int32_t max) +{ + int32_t wants_bytes; + uint32_t total_len; + uint32_t want_bytes_pending; + if (parser->bytes_fed < KMS_KMIP_RESPONSE_PARSER_FIRST_LENGTH) { + wants_bytes = + KMS_KMIP_RESPONSE_PARSER_FIRST_LENGTH - (int32_t) parser->bytes_fed; + } else { + KMS_ASSERT (parser->first_len <= + UINT32_MAX - KMS_KMIP_RESPONSE_PARSER_FIRST_LENGTH); + total_len = parser->first_len + KMS_KMIP_RESPONSE_PARSER_FIRST_LENGTH; + KMS_ASSERT (total_len >= parser->bytes_fed); + want_bytes_pending = total_len - parser->bytes_fed; + KMS_ASSERT (want_bytes_pending <= (uint32_t) INT32_MAX); + wants_bytes = (int32_t) want_bytes_pending; + } + if (max < wants_bytes) { + return max; + } + return wants_bytes; +} + +bool +kms_kmip_response_parser_feed (kms_kmip_response_parser_t *parser, + const uint8_t *buf, + uint32_t len) +{ + kms_request_str_append_chars (parser->buf, (char *) buf, len); + parser->bytes_fed += len; + + if (parser->first_len > 0) { + if (parser->bytes_fed > + parser->first_len + KMS_KMIP_RESPONSE_PARSER_FIRST_LENGTH) { + KMS_ERROR (parser, "KMIP parser was fed too much data"); + return false; + } + } else if (parser->first_len == 0 && + parser->bytes_fed >= KMS_KMIP_RESPONSE_PARSER_FIRST_LENGTH) { + uint32_t temp; + memcpy (&temp, parser->buf->str + FIRST_LENGTH_OFFSET, sizeof (uint32_t)); + parser->first_len = KMS_UINT32_FROM_BE (temp); + } + return true; +} + +kms_response_t * +kms_kmip_response_parser_get_response (kms_kmip_response_parser_t *parser) +{ + kms_response_t *res; + + if (kms_kmip_response_parser_wants_bytes (parser, 1) != 0) { + KMS_ERROR (parser, "KMIP parser does not have a complete message"); + return NULL; + } + + res = calloc (1, sizeof (kms_response_t)); + res->provider = KMS_REQUEST_PROVIDER_KMIP; + res->kmip.len = (uint32_t) parser->buf->len; + res->kmip.data = (uint8_t *) kms_request_str_detach (parser->buf); + parser->buf = NULL; + + /* Reinitialize for reuse. */ + _parser_destroy (parser); + _parser_init (parser); + return res; +} + +const char * +kms_kmip_response_parser_error (const kms_kmip_response_parser_t *parser) +{ + return parser->failed ? parser->error : NULL; +} + +void +kms_kmip_response_parser_destroy (kms_kmip_response_parser_t *parser) +{ + if (!parser) { + return; + } + + _parser_destroy (parser); + free (parser); +} diff --git a/src/kms/kms_kmip_response_parser_private.h b/src/kms/kms_kmip_response_parser_private.h new file mode 100644 index 00000000..5dfe8e45 --- /dev/null +++ b/src/kms/kms_kmip_response_parser_private.h @@ -0,0 +1,55 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_KMIP_RESPONSE_PARSER_PRIVATE_H +#define KMS_KMIP_RESPONSE_PARSER_PRIVATE_H + +#include "kms_message/kms_response.h" + +#include +#include + +/* kms_kmip_response_parser_t is a private type used for parsing a KMIP + * response. */ +typedef struct _kms_kmip_response_parser_t kms_kmip_response_parser_t; + +/* KMS_KMIP_RESPONSE_PARSER_FIRST_LENGTH is the number of bytes needed by the + * parser to determine the total length of the message being parsed. + * It includes the first Length in a TTLV sequence. The sequence is: Tag (3 + * bytes), Type (1 byte), Length (4 bytes), Value (Length bytes). */ +#define KMS_KMIP_RESPONSE_PARSER_FIRST_LENGTH 8 + +int32_t +kms_kmip_response_parser_wants_bytes (const kms_kmip_response_parser_t *parser, + int32_t max); + +bool +kms_kmip_response_parser_feed (kms_kmip_response_parser_t *parser, + const uint8_t *buf, + uint32_t len); + +/* kms_kmip_response_parser_get_response returns a kms_response_t and resets the + * parser. */ +kms_response_t * +kms_kmip_response_parser_get_response (kms_kmip_response_parser_t *parser); + +void +kms_kmip_response_parser_destroy (kms_kmip_response_parser_t *parser); + +const char * +kms_kmip_response_parser_error (const kms_kmip_response_parser_t *parser); + +#endif /* KMS_KMIP_RESPONSE_PARSER_PRIVATE_H */ diff --git a/src/kms/kms_kmip_result_reason_private.h b/src/kms/kms_kmip_result_reason_private.h new file mode 100644 index 00000000..edd4262d --- /dev/null +++ b/src/kms/kms_kmip_result_reason_private.h @@ -0,0 +1,77 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_KMIP_RESULT_REASON_PRIVATE_H +#define KMS_KMIP_RESULT_REASON_PRIVATE_H + +#include "kms_message/kms_message_defines.h" + +/* clang-format off */ +#define KMS_XMACRO \ + KMS_X (ItemNotFound, "Item Not Found", 0x00000001) \ + KMS_X (ResponseTooLarge, "Response Too Large", 0x00000002) \ + KMS_X (AuthenticationNotSuccessful, "Authentication Not Successful", 0x00000003) \ + KMS_X (InvalidMessage, "Invalid Message", 0x00000004) \ + KMS_X (OperationNotSupported, "Operation Not Supported", 0x00000005) \ + KMS_X (MissingData, "Missing Data", 0x00000006) \ + KMS_X (InvalidField, "Invalid Field", 0x00000007) \ + KMS_X (FeatureNotSupported, "Feature Not Supported", 0x00000008) \ + KMS_X (OperationCanceledByRequester, "Operation Canceled By Requester", 0x00000009) \ + KMS_X (CryptographicFailure, "Cryptographic Failure", 0x0000000A) \ + KMS_X (IllegalOperation, "Illegal Operation", 0x0000000B) \ + KMS_X (PermissionDenied, "Permission Denied", 0x0000000C) \ + KMS_X (Objectarchived, "Object archived", 0x0000000D) \ + KMS_X (IndexOutofBounds, "Index Out of Bounds", 0x0000000E) \ + KMS_X (ApplicationNamespaceNotSupported, "Application Namespace Not Supported", 0x0000000F) \ + KMS_X (KeyFormatTypeNotSupported, "Key Format Type Not Supported", 0x00000010) \ + KMS_X (KeyCompressionTypeNotSupported, "Key Compression Type Not Supported", 0x00000011) \ + KMS_X (EncodingOptionError, "Encoding Option Error", 0x00000012) \ + KMS_X (KeyValueNotPresent, "Key Value Not Present", 0x00000013) \ + KMS_X (AttestationRequired, "Attestation Required", 0x00000014) \ + KMS_X (AttestationFailed, "Attestation Failed", 0x00000015) \ + KMS_X (Sensitive, "Sensitive", 0x00000016) \ + KMS_X (NotExtractable, "Not Extractable", 0x00000017) \ + KMS_X (ObjectAlreadyExists, "Object Already Exists", 0x00000018) \ + KMS_X_LAST (GeneralFailure, "General Failure", 0x00000100) +/* clang-format on */ + +/* Generate an enum with each result_reason value. */ +#define KMS_X(RESULT_REASON, STR, VAL) KMIP_RESULT_REASON_##RESULT_REASON = VAL, +#define KMS_X_LAST(RESULT_REASON, STR, VAL) \ + KMIP_RESULT_REASON_##RESULT_REASON = VAL +typedef enum { KMS_XMACRO } kmip_result_reason_t; +#undef KMS_X +#undef KMS_X_LAST + +#define KMS_X(RESULT_REASON, STR, VAL) \ + case KMIP_RESULT_REASON_##RESULT_REASON: \ + return STR; +#define KMS_X_LAST KMS_X +static KMS_MSG_INLINE const char * +kmip_result_reason_to_string (kmip_result_reason_t result_reason) +{ + switch (result_reason) { + default: + return "Unknown KMIP result reason"; + KMS_XMACRO + } +} +#undef KMS_X +#undef KMS_X_LAST + +#undef KMS_XMACRO + +#endif /* KMS_KMIP_RESULT_REASON_PRIVATE_H */ diff --git a/src/kms/kms_kmip_result_status_private.h b/src/kms/kms_kmip_result_status_private.h new file mode 100644 index 00000000..39701d8d --- /dev/null +++ b/src/kms/kms_kmip_result_status_private.h @@ -0,0 +1,54 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_KMIP_RESULT_STATUS_PRIVATE_H +#define KMS_KMIP_RESULT_STATUS_PRIVATE_H + +#include "kms_message/kms_message_defines.h" + +#define KMS_XMACRO \ + KMS_X (OperationSuccess, "Success", 0x00000000) \ + KMS_X (OperationFailed, "Operation Failed", 0x00000001) \ + KMS_X (OperationPending, "Operation Pending", 0x00000002) \ + KMS_X_LAST (OperationUndone, "Operation Undone", 0x00000003) + +/* Generate an enum with each result_status value. */ +#define KMS_X(RESULT_STATUS, STR, VAL) KMIP_RESULT_STATUS_##RESULT_STATUS = VAL, +#define KMS_X_LAST(RESULT_STATUS, STR, VAL) \ + KMIP_RESULT_STATUS_##RESULT_STATUS = VAL +typedef enum { KMS_XMACRO } kmip_result_status_t; +#undef KMS_X +#undef KMS_X_LAST + +#define KMS_X(RESULT_STATUS, STR, VAL) \ + case KMIP_RESULT_STATUS_##RESULT_STATUS: \ + return STR; +#define KMS_X_LAST KMS_X +static KMS_MSG_INLINE const char * +kmip_result_status_to_string (kmip_result_status_t result_status) +{ + switch (result_status) { + default: + return "Unknown KMIP result status"; + KMS_XMACRO + } +} +#undef KMS_X +#undef KMS_X_LAST + +#undef KMS_XMACRO + +#endif /* KMS_KMIP_RESULT_STATUS_PRIVATE_H */ diff --git a/src/kms/kms_kmip_tag_type_private.h b/src/kms/kms_kmip_tag_type_private.h new file mode 100644 index 00000000..293ff159 --- /dev/null +++ b/src/kms/kms_kmip_tag_type_private.h @@ -0,0 +1,343 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_KMIP_TAG_TYPE_PRIVATE_H +#define KMS_KMIP_TAG_TYPE_PRIVATE_H + +#include "kms_message/kms_message_defines.h" + +/* clang-format off */ +#define KMS_XMACRO \ + KMS_X (ActivationDate, 0x420001) \ + KMS_X (ApplicationData, 0x420002) \ + KMS_X (ApplicationNamespace, 0x420003) \ + KMS_X (ApplicationSpecificInformation, 0x420004) \ + KMS_X (ArchiveDate, 0x420005) \ + KMS_X (AsynchronousCorrelationValue, 0x420006) \ + KMS_X (AsynchronousIndicator, 0x420007) \ + KMS_X (Attribute, 0x420008) \ + KMS_X (AttributeIndex, 0x420009) \ + KMS_X (AttributeName, 0x42000A) \ + KMS_X (AttributeValue, 0x42000B) \ + KMS_X (Authentication, 0x42000C) \ + KMS_X (BatchCount, 0x42000D) \ + KMS_X (BatchErrorContinuationOption, 0x42000E) \ + KMS_X (BatchItem, 0x42000F) \ + KMS_X (BatchOrderOption, 0x420010) \ + KMS_X (BlockCipherMode, 0x420011) \ + KMS_X (CancellationResult, 0x420012) \ + KMS_X (Certificate, 0x420013) \ + KMS_X (CertificateIdentifier, 0x420014) /* deprecated as of version 1.1 */ \ + KMS_X (CertificateIssuer, 0x420015) /* deprecated as of version 1.1 */ \ + KMS_X (CertificateIssuerAlternativeName, 0x420016) /* deprecated as of version 1.1 */ \ + KMS_X (CertificateIssuerDistinguishedName, 0x420017) /* deprecated as of version 1.1 */ \ + KMS_X (CertificateRequest, 0x420018) \ + KMS_X (CertificateRequestType, 0x420019) \ + KMS_X (CertificateSubject, 0x42001A) /* deprecated as of version 1.1 */ \ + KMS_X (CertificateSubjectAlternativeName, 0x42001B) /* deprecated as of version 1.1 */ \ + KMS_X (CertificateSubjectDistinguishedName, 0x42001C) /* deprecated as of version 1.1 */ \ + KMS_X (CertificateType, 0x42001D) \ + KMS_X (CertificateValue, 0x42001E) \ + KMS_X (CommonTemplateAttribute, 0x42001F) \ + KMS_X (CompromiseDate, 0x420020) \ + KMS_X (CompromiseOccurrenceDate, 0x420021) \ + KMS_X (ContactInformation, 0x420022) \ + KMS_X (Credential, 0x420023) \ + KMS_X (CredentialType, 0x420024) \ + KMS_X (CredentialValue, 0x420025) \ + KMS_X (CriticalityIndicator, 0x420026) \ + KMS_X (CRTCoefficient, 0x420027) \ + KMS_X (CryptographicAlgorithm, 0x420028) \ + KMS_X (CryptographicDomainParameters, 0x420029) \ + KMS_X (CryptographicLength, 0x42002A) \ + KMS_X (CryptographicParameters, 0x42002B) \ + KMS_X (CryptographicUsageMask, 0x42002C) \ + KMS_X (CustomAttribute, 0x42002D) \ + KMS_X (D, 0x42002E) \ + KMS_X (DeactivationDate, 0x42002F) \ + KMS_X (DerivationData, 0x420030) \ + KMS_X (DerivationMethod, 0x420031) \ + KMS_X (DerivationParameters, 0x420032) \ + KMS_X (DestroyDate, 0x420033) \ + KMS_X (Digest, 0x420034) \ + KMS_X (DigestValue, 0x420035) \ + KMS_X (EncryptionKeyInformation, 0x420036) \ + KMS_X (G, 0x420037) \ + KMS_X (HashingAlgorithm, 0x420038) \ + KMS_X (InitialDate, 0x420039) \ + KMS_X (InitializationVector, 0x42003A) \ + KMS_X (Issuer, 0x42003B) /* deprecated as of version 1.1 */ \ + KMS_X (IterationCount, 0x42003C) \ + KMS_X (IVCounterNonce, 0x42003D) \ + KMS_X (J, 0x42003E) \ + KMS_X (Key, 0x42003F) \ + KMS_X (KeyBlock, 0x420040) \ + KMS_X (KeyCompressionType, 0x420041) \ + KMS_X (KeyFormatType, 0x420042) \ + KMS_X (KeyMaterial, 0x420043) \ + KMS_X (KeyPartIdentifier, 0x420044) \ + KMS_X (KeyValue, 0x420045) \ + KMS_X (KeyWrappingData, 0x420046) \ + KMS_X (KeyWrappingSpecification, 0x420047) \ + KMS_X (LastChangeDate, 0x420048) \ + KMS_X (LeaseTime, 0x420049) \ + KMS_X (Link, 0x42004A) \ + KMS_X (LinkType, 0x42004B) \ + KMS_X (LinkedObjectIdentifier, 0x42004C) \ + KMS_X (MACSignature, 0x42004D) \ + KMS_X (MACSignatureKeyInformation, 0x42004E) \ + KMS_X (MaximumItems, 0x42004F) \ + KMS_X (MaximumResponseSize, 0x420050) \ + KMS_X (MessageExtension, 0x420051) \ + KMS_X (Modulus, 0x420052) \ + KMS_X (Name, 0x420053) \ + KMS_X (NameType, 0x420054) \ + KMS_X (NameValue, 0x420055) \ + KMS_X (ObjectGroup, 0x420056) \ + KMS_X (ObjectType, 0x420057) \ + KMS_X (Offset, 0x420058) \ + KMS_X (OpaqueDataType, 0x420059) \ + KMS_X (OpaqueDataValue, 0x42005A) \ + KMS_X (OpaqueObject, 0x42005B) \ + KMS_X (Operation, 0x42005C) \ + KMS_X (OperationPolicyName, 0x42005D) /* deprecated */ \ + KMS_X (P, 0x42005E) \ + KMS_X (PaddingMethod, 0x42005F) \ + KMS_X (PrimeExponentP, 0x420060) \ + KMS_X (PrimeExponentQ, 0x420061) \ + KMS_X (PrimeFieldSize, 0x420062) \ + KMS_X (PrivateExponent, 0x420063) \ + KMS_X (PrivateKey, 0x420064) \ + KMS_X (PrivateKeyTemplateAttribute, 0x420065) \ + KMS_X (PrivateKeyUniqueIdentifier, 0x420066) \ + KMS_X (ProcessStartDate, 0x420067) \ + KMS_X (ProtectStopDate, 0x420068) \ + KMS_X (ProtocolVersion, 0x420069) \ + KMS_X (ProtocolVersionMajor, 0x42006A) \ + KMS_X (ProtocolVersionMinor, 0x42006B) \ + KMS_X (PublicExponent, 0x42006C) \ + KMS_X (PublicKey, 0x42006D) \ + KMS_X (PublicKeyTemplateAttribute, 0x42006E) \ + KMS_X (PublicKeyUniqueIdentifier, 0x42006F) \ + KMS_X (PutFunction, 0x420070) \ + KMS_X (Q, 0x420071) \ + KMS_X (QString, 0x420072) \ + KMS_X (Qlength, 0x420073) \ + KMS_X (QueryFunction, 0x420074) \ + KMS_X (RecommendedCurve, 0x420075) \ + KMS_X (ReplacedUniqueIdentifier, 0x420076) \ + KMS_X (RequestHeader, 0x420077) \ + KMS_X (RequestMessage, 0x420078) \ + KMS_X (RequestPayload, 0x420079) \ + KMS_X (ResponseHeader, 0x42007A) \ + KMS_X (ResponseMessage, 0x42007B) \ + KMS_X (ResponsePayload, 0x42007C) \ + KMS_X (ResultMessage, 0x42007D) \ + KMS_X (ResultReason, 0x42007E) \ + KMS_X (ResultStatus, 0x42007F) \ + KMS_X (RevocationMessage, 0x420080) \ + KMS_X (RevocationReason, 0x420081) \ + KMS_X (RevocationReasonCode, 0x420082) \ + KMS_X (KeyRoleType, 0x420083) \ + KMS_X (Salt, 0x420084) \ + KMS_X (SecretData, 0x420085) \ + KMS_X (SecretDataType, 0x420086) \ + KMS_X (SerialNumber, 0x420087) /* deprecated as of version 1.1 */ \ + KMS_X (ServerInformation, 0x420088) \ + KMS_X (SplitKey, 0x420089) \ + KMS_X (SplitKeyMethod, 0x42008A) \ + KMS_X (SplitKeyParts, 0x42008B) \ + KMS_X (SplitKeyThreshold, 0x42008C) \ + KMS_X (State, 0x42008D) \ + KMS_X (StorageStatusMask, 0x42008E) \ + KMS_X (SymmetricKey, 0x42008F) \ + KMS_X (Template, 0x420090) \ + KMS_X (TemplateAttribute, 0x420091) \ + KMS_X (TimeStamp, 0x420092) \ + KMS_X (UniqueBatchItemID, 0x420093) \ + KMS_X (UniqueIdentifier, 0x420094) \ + KMS_X (UsageLimits, 0x420095) \ + KMS_X (UsageLimitsCount, 0x420096) \ + KMS_X (UsageLimitsTotal, 0x420097) \ + KMS_X (UsageLimitsUnit, 0x420098) \ + KMS_X (Username, 0x420099) \ + KMS_X (ValidityDate, 0x42009A) \ + KMS_X (ValidityIndicator, 0x42009B) \ + KMS_X (VendorExtension, 0x42009C) \ + KMS_X (VendorIdentification, 0x42009D) \ + KMS_X (WrappingMethod, 0x42009E) \ + KMS_X (X, 0x42009F) \ + KMS_X (Y, 0x4200A0) \ + KMS_X (Password, 0x4200A1) \ + KMS_X (DeviceIdentifier, 0x4200A2) \ + KMS_X (EncodingOption, 0x4200A3) \ + KMS_X (ExtensionInformation, 0x4200A4) \ + KMS_X (ExtensionName, 0x4200A5) \ + KMS_X (ExtensionTag, 0x4200A6) \ + KMS_X (ExtensionType, 0x4200A7) \ + KMS_X (Fresh, 0x4200A8) \ + KMS_X (MachineIdentifier, 0x4200A9) \ + KMS_X (MediaIdentifier, 0x4200AA) \ + KMS_X (NetworkIdentifier, 0x4200AB) \ + KMS_X (ObjectGroupMember, 0x4200AC) \ + KMS_X (CertificateLength, 0x4200AD) \ + KMS_X (DigitalSignatureAlgorithm, 0x4200AE) \ + KMS_X (CertificateSerialNumber, 0x4200AF) \ + KMS_X (DeviceSerialNumber, 0x4200B0) \ + KMS_X (IssuerAlternativeName, 0x4200B1) \ + KMS_X (IssuerDistinguishedName, 0x4200B2) \ + KMS_X (SubjectAlternativeName, 0x4200B3) \ + KMS_X (SubjectDistinguishedName, 0x4200B4) \ + KMS_X (X509CertificateIdentifier, 0x4200B5) \ + KMS_X (X509CertificateIssuer, 0x4200B6) \ + KMS_X (X509CertificateSubject, 0x4200B7) \ + KMS_X (KeyValueLocation, 0x4200B8) \ + KMS_X (KeyValueLocationValue, 0x4200B9) \ + KMS_X (KeyValueLocationType, 0x4200BA) \ + KMS_X (KeyValuePresent, 0x4200BB) \ + KMS_X (OriginalCreationDate, 0x4200BC) \ + KMS_X (PGPKey, 0x4200BD) \ + KMS_X (PGPKeyVersion, 0x4200BE) \ + KMS_X (AlternativeName, 0x4200BF) \ + KMS_X (AlternativeNameValue, 0x4200C0) \ + KMS_X (AlternativeNameType, 0x4200C1) \ + KMS_X (Data, 0x4200C2) \ + KMS_X (SignatureData, 0x4200C3) \ + KMS_X (DataLength, 0x4200C4) \ + KMS_X (RandomIV, 0x4200C5) \ + KMS_X (MACData, 0x4200C6) \ + KMS_X (AttestationType, 0x4200C7) \ + KMS_X (Nonce, 0x4200C8) \ + KMS_X (NonceID, 0x4200C9) \ + KMS_X (NonceValue, 0x4200CA) \ + KMS_X (AttestationMeasurement, 0x4200CB) \ + KMS_X (AttestationAssertion, 0x4200CC) \ + KMS_X (IVLength, 0x4200CD) \ + KMS_X (TagLength, 0x4200CE) \ + KMS_X (FixedFieldLength, 0x4200CF) \ + KMS_X (CounterLength, 0x4200D0) \ + KMS_X (InitialCounterValue, 0x4200D1) \ + KMS_X (InvocationFieldLength, 0x4200D2) \ + KMS_X (AttestationCapableIndicator, 0x4200D3) \ + KMS_X (OffsetItems, 0x4200D4) \ + KMS_X (LocatedItems, 0x4200D5) \ + KMS_X (CorrelationValue, 0x4200D6) \ + KMS_X (InitIndicator, 0x4200D7) \ + KMS_X (FinalIndicator, 0x4200D8) \ + KMS_X (RNGParameters, 0x4200D9) \ + KMS_X (RNGAlgorithm, 0x4200DA) \ + KMS_X (DRBGAlgorithm, 0x4200DB) \ + KMS_X (FIPS186Variation, 0x4200DC) \ + KMS_X (PredictionResistance, 0x4200DD) \ + KMS_X (RandomNumberGenerator, 0x4200DE) \ + KMS_X (ValidationInformation, 0x4200DF) \ + KMS_X (ValidationAuthorityType, 0x4200E0) \ + KMS_X (ValidationAuthorityCountry, 0x4200E1) \ + KMS_X (ValidationAuthorityURI, 0x4200E2) \ + KMS_X (ValidationVersionMajor, 0x4200E3) \ + KMS_X (ValidationVersionMinor, 0x4200E4) \ + KMS_X (ValidationType, 0x4200E5) \ + KMS_X (ValidationLevel, 0x4200E6) \ + KMS_X (ValidationCertificateIdentifier, 0x4200E7) \ + KMS_X (ValidationCertificateURI, 0x4200E8) \ + KMS_X (ValidationVendorURI, 0x4200E9) \ + KMS_X (ValidationProfile, 0x4200EA) \ + KMS_X (ProfileInformation, 0x4200EB) \ + KMS_X (ProfileName, 0x4200EC) \ + KMS_X (ServerURI, 0x4200ED) \ + KMS_X (ServerPort, 0x4200EE) \ + KMS_X (StreamingCapability, 0x4200EF) \ + KMS_X (AsynchronousCapability, 0x4200F0) \ + KMS_X (AttestationCapability, 0x4200F1) \ + KMS_X (UnwrapMode, 0x4200F2) \ + KMS_X (DestroyAction, 0x4200F3) \ + KMS_X (ShreddingAlgorithm, 0x4200F4) \ + KMS_X (RNGMode, 0x4200F5) \ + KMS_X (ClientRegistrationMethod, 0x4200F6) \ + KMS_X (CapabilityInformation, 0x4200F7) \ + KMS_X (KeyWrapType, 0x4200F8) \ + KMS_X (BatchUndoCapability, 0x4200F9) \ + KMS_X (BatchContinueCapability, 0x4200FA) \ + KMS_X (PKCS12FriendlyName, 0x4200FB) \ + KMS_X (Description, 0x4200FC) \ + KMS_X (Comment, 0x4200FD) \ + KMS_X (AuthenticatedEncryptionAdditionalData, 0x4200FE) \ + KMS_X (AuthenticatedEncryptionTag, 0x4200FF) \ + KMS_X (SaltLength, 0x420100) \ + KMS_X (MaskGenerator, 0x420101) \ + KMS_X (MaskGeneratorHashingAlgorithm, 0x420102) \ + KMS_X (PSource, 0x420103) \ + KMS_X (TrailerField, 0x420104) \ + KMS_X (ClientCorrelationValue, 0x420105) \ + KMS_X (ServerCorrelationValue, 0x420106) \ + KMS_X (DigestedData, 0x420107) \ + KMS_X (CertificateSubjectCN, 0x420108) \ + KMS_X (CertificateSubjectO, 0x420109) \ + KMS_X (CertificateSubjectOU, 0x42010A) \ + KMS_X (CertificateSubjectEmail, 0x42010B) \ + KMS_X (CertificateSubjectC, 0x42010C) \ + KMS_X (CertificateSubjectST, 0x42010D) \ + KMS_X (CertificateSubjectL, 0x42010E) \ + KMS_X (CertificateSubjectUID, 0x42010F) \ + KMS_X (CertificateSubjectSerialNumber, 0x420110) \ + KMS_X (CertificateSubjectTitle, 0x420111) \ + KMS_X (CertificateSubjectDC, 0x420112) \ + KMS_X (CertificateSubjectDNQualifier, 0x420113) \ + KMS_X (CertificateIssuerCN, 0x420114) \ + KMS_X (CertificateIssuerO, 0x420115) \ + KMS_X (CertificateIssuerOU, 0x420116) \ + KMS_X (CertificateIssuerEmail, 0x420117) \ + KMS_X (CertificateIssuerC, 0x420118) \ + KMS_X (CertificateIssuerST, 0x420119) \ + KMS_X (CertificateIssuerL, 0x42011A) \ + KMS_X (CertificateIssuerUID, 0x42011B) \ + KMS_X (CertificateIssuerSerialNumber, 0x42011C) \ + KMS_X (CertificateIssuerTitle, 0x42011D) \ + KMS_X (CertificateIssuerDC, 0x42011E) \ + KMS_X (CertificateIssuerDNQualifier, 0x42011F) \ + KMS_X (Sensitive, 0x420120) \ + KMS_X (AlwaysSensitive, 0x420121) \ + KMS_X (Extractable, 0x420122) \ + KMS_X (NeverExtractable, 0x420123) \ + KMS_X_LAST (ReplaceExisting, 0x420124) +/* clang-format on */ + +/* Generate an enum with each tag value. */ +#define KMS_X(TAG, VAL) KMIP_TAG_##TAG = VAL, +#define KMS_X_LAST(TAG, VAL) KMIP_TAG_##TAG = VAL +typedef enum { KMS_XMACRO } kmip_tag_type_t; +#undef KMS_X +#undef KMS_X_LAST + +#define KMS_X(TAG, VAL) \ + case KMIP_TAG_##TAG: \ + return #TAG; +#define KMS_X_LAST KMS_X +static KMS_MSG_INLINE const char * +kmip_tag_to_string (kmip_tag_type_t tag) +{ + switch (tag) { + default: + return "Unknown KMIP tag"; + KMS_XMACRO + } +} +#undef KMS_X +#undef KMS_X_LAST + +#undef KMS_XMACRO + +#endif /* KMS_KMIP_TAG_TYPE_PRIVATE_H */ diff --git a/src/kms/kms_message/kms_azure_request.h b/src/kms/kms_message/kms_azure_request.h new file mode 100644 index 00000000..2e9af68f --- /dev/null +++ b/src/kms/kms_message/kms_azure_request.h @@ -0,0 +1,110 @@ +/* + * Copyright 2020-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_AZURE_REQUEST_H +#define KMS_AZURE_REQUEST_H + +#include "kms_message_defines.h" +#include "kms_request.h" +#include "kms_request_opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Constructs an oauth client credentials grant request for Azure. + * See + * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#get-a-token. + * + * Parameters: + * All parameters must be NULL terminated strings. + * - host: The value of the Host header. This should be a custom host or + * "login.microsoftonline.com". + * - scope: The oauth scope. This should be a custom scope or + * "https%3A%2F%2Fvault.azure.net%2F.default". Must be URL encoded. + * - tenant_id: The Azure tenant ID. + * - client_id: The client ID to authenticate. + * - client_secret: The client secret to authenticate. + * - opt: Additional options. This must have the Azure provider set via + * kms_request_opt_set_provider. + * + * Returns: A new kms_request_t. + * Always returns a new kms_request_t, even on error. + * Caller must check if an error occurred by calling kms_request_get_error. + */ +KMS_MSG_EXPORT (kms_request_t *) +kms_azure_request_oauth_new (const char *host, + const char *scope, + const char *tenant_id, + const char *client_id, + const char *client_secret, + const kms_request_opt_t *opt); + +/* Constructs a wrapkey request for Azure. + * See https://docs.microsoft.com/en-us/rest/api/keyvault/wrapkey/wrapkey + * + * Parameters: + * All parameters must be NULL terminated strings. + * - host: The value of the Host header, like "mykeyvault.vault.azure.net". + * - access_token: The access_token obtained from an oauth response as a + * base64url encoded string. + * - key_name: The azure key name. + * - key_version: An optional key version. May be NULL or empty string. + * - plaintext: The plaintext key to encrypt. + * - plaintext_len: The number of bytes of plaintext. + * - opt: Additional options. This must have the Azure provider set via + * kms_request_opt_set_provider. + */ + +KMS_MSG_EXPORT (kms_request_t *) +kms_azure_request_wrapkey_new (const char *host, + const char *access_token, + const char *key_name, + const char *key_version, + const uint8_t *plaintext, + size_t plaintext_len, + const kms_request_opt_t *opt); + +/* Constructs an unwrapkey request for Azure. + * See https://docs.microsoft.com/en-us/rest/api/keyvault/unwrapkey/unwrapkey + * + * Parameters: + * All parameters must be NULL terminated strings. + * - host: The value of the Host header, like "mykeyvault.vault.azure.net". + * - access_token: The access_token obtained from an oauth response as a + * base64url encoded string. + * - key_name: The azure key name. + * - key_version: An optional key version. May be NULL or empty string. + * - ciphertext: The ciphertext key to decrypt. + * - ciphertext_len: The number of bytes of ciphertext. + * - opt: Additional options. This must have the Azure provider set via + * kms_request_opt_set_provider. + */ + +KMS_MSG_EXPORT (kms_request_t *) +kms_azure_request_unwrapkey_new (const char *host, + const char *access_token, + const char *key_name, + const char *key_version, + const uint8_t *ciphertext, + size_t ciphertext_len, + const kms_request_opt_t *opt); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* KMS_AZURE_REQUEST_H */ diff --git a/src/kms/kms_message/kms_b64.h b/src/kms/kms_message/kms_b64.h index a55c1ec9..f0845cd3 100644 --- a/src/kms/kms_message/kms_b64.h +++ b/src/kms/kms_message/kms_b64.h @@ -38,6 +38,31 @@ kms_message_b64_ntop (uint8_t const *src, KMS_MSG_EXPORT (int) kms_message_b64_pton (char const *src, uint8_t *target, size_t targsize); +/* src and target may be the same string. Assumes no whitespace in src. */ +KMS_MSG_EXPORT (int) +kms_message_b64_to_b64url (const char *src, + size_t srclength, + char *target, + size_t targsize); +KMS_MSG_EXPORT (int) +kms_message_b64url_to_b64 (const char *src, + size_t srclength, + char *target, + size_t targsize); + +/* Convenience conversions which return copies. */ +char * +kms_message_raw_to_b64 (const uint8_t *raw, size_t raw_len); + +uint8_t * +kms_message_b64_to_raw (const char *b64, size_t *out); + +char * +kms_message_raw_to_b64url (const uint8_t *raw, size_t raw_len); + +uint8_t * +kms_message_b64url_to_raw (const char *b64url, size_t *out); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/kms/kms_message/kms_caller_identity_request.h b/src/kms/kms_message/kms_caller_identity_request.h index 9af8e2cc..9f48e534 100644 --- a/src/kms/kms_message/kms_caller_identity_request.h +++ b/src/kms/kms_message/kms_caller_identity_request.h @@ -17,7 +17,9 @@ #ifndef KMS_CALLER_IDENTITY_REQUEST_H #define KMS_CALLER_IDENTITY_REQUEST_H -#include "kms_message.h" +#include "kms_message_defines.h" +#include "kms_request.h" +#include "kms_request_opt.h" #ifdef __cplusplus extern "C" { diff --git a/src/kms/kms_message/kms_decrypt_request.h b/src/kms/kms_message/kms_decrypt_request.h index b27a96d9..db18d5f5 100644 --- a/src/kms/kms_message/kms_decrypt_request.h +++ b/src/kms/kms_message/kms_decrypt_request.h @@ -17,7 +17,9 @@ #ifndef KMS_DECRYPT_REQUEST_H #define KMS_DECRYPT_REQUEST_H -#include "kms_message.h" +#include "kms_message_defines.h" +#include "kms_request.h" +#include "kms_request_opt.h" #ifdef __cplusplus extern "C" { diff --git a/src/kms/kms_message/kms_encrypt_request.h b/src/kms/kms_message/kms_encrypt_request.h index ac30f1a3..601ee362 100644 --- a/src/kms/kms_message/kms_encrypt_request.h +++ b/src/kms/kms_message/kms_encrypt_request.h @@ -17,7 +17,9 @@ #ifndef KMS_ENCRYPT_REQUEST_H #define KMS_ENCRYPT_REQUEST_H -#include "kms_message.h" +#include "kms_message_defines.h" +#include "kms_request.h" +#include "kms_request_opt.h" #ifdef __cplusplus extern "C" { diff --git a/src/kms/kms_message/kms_gcp_request.h b/src/kms/kms_message/kms_gcp_request.h new file mode 100644 index 00000000..1d1555fb --- /dev/null +++ b/src/kms/kms_message/kms_gcp_request.h @@ -0,0 +1,124 @@ +/* + * Copyright 2020-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_GCP_REQUEST_H +#define KMS_GCP_REQUEST_H + +#include "kms_message_defines.h" +#include "kms_request.h" +#include "kms_request_opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Constructs an oauth client credentials request for GCP. + * See https://developers.google.com/identity/protocols/oauth2/service-account + * + * Parameters: + * - host: The host header, like "oauth2.googleapis.com". + * - email: The email for the service account to authenticate. + * - audience: The "aud" field in the JSON Web Token (JWT). Should be a URL + * like "https://oauth2.googleapis.com/token" + * - scope: The "scope" field in the JSON Web Token (JWT). Should be a URL + * like "https://www.googleapis.com/auth/cloudkms". + * - private_key_data: Bytes pointing to a PKCS#8 private key. + * - private_key_len: The length of private_key_data. + * - opt: Request options. The provider must be set to KMS_REQUEST_PROVIDER_GCP + * with kms_request_opt_set_provider. Callers that want to use a custom crypto + * callback to sign the request should set the callback on opt with + * kms_request_opt_set_crypto_hook_rsaes_pkcs1_v1_5. + * + * Returns: A new kms_request_t. + * Always returns a new kms_request_t, even on error. + * Caller must check if an error occurred by calling kms_request_get_error. + */ +KMS_MSG_EXPORT (kms_request_t *) +kms_gcp_request_oauth_new (const char *host, + const char *email, + const char *audience, + const char *scope, + const char *private_key_data, + size_t private_key_len, + const kms_request_opt_t *opt); + +/* Constructs the encrypt request for GCP. + * See + * https://cloud.google.com/kms/docs/encrypt-decrypt#kms-encrypt-symmetric-api + * + * Parameters: + * - host: The value of the Host header, like "cloudkms.googleapis.com". + * - project_id: The project id. + * - location: The location id, like "global". + * - key_ring_name: The key ring name. + * - key_name: The key name. + * - key_version: The optional key version. May be NULL. + * - plaintext: The plaintext key to encrypt. + * - plaintext_len: The number of bytes of plaintext. + * - opt: Request options. The provider must be set to KMS_REQUEST_PROVIDER_GCP + * with kms_request_opt_set_provider. + * + * Returns: A new kms_request_t. + * Always returns a new kms_request_t, even on error. + * Caller must check if an error occurred by calling kms_request_get_error. + */ +KMS_MSG_EXPORT (kms_request_t *) +kms_gcp_request_encrypt_new (const char *host, + const char *access_token, + const char *project_id, + const char *location, + const char *key_ring_name, + const char *key_name, + const char *key_version, + const uint8_t *plaintext, + size_t plaintext_len, + const kms_request_opt_t *opt); + +/* Constructs the decrypt request for GCP. + * See + * https://cloud.google.com/kms/docs/encrypt-decrypt#kms-decrypt-symmetric-api + * + * Parameters: + * - host: The value of the Host header, like "cloudkms.googleapis.com". + * - project_id: The project id. + * - location: The location id, like "global". + * - key_ring_name: The key ring name. + * - key_name: The key name. + * - ciphertext: The ciphertext key to encrypt. + * - ciphertext_len: The number of bytes of ciphertext. + * - opt: Request options. The provider must be set to KMS_REQUEST_PROVIDER_GCP + * with kms_request_opt_set_provider. + * + * Returns: A new kms_request_t. + * Always returns a new kms_request_t, even on error. + * Caller must check if an error occurred by calling kms_request_get_error. + */ +KMS_MSG_EXPORT (kms_request_t *) +kms_gcp_request_decrypt_new (const char *host, + const char *access_token, + const char *project_id, + const char *location, + const char *key_ring_name, + const char *key_name, + const uint8_t *ciphertext, + size_t ciphertext_len, + const kms_request_opt_t *opt); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* KMS_GCP_REQUEST_H */ diff --git a/src/kms/kms_message/kms_kmip_request.h b/src/kms/kms_message/kms_kmip_request.h new file mode 100644 index 00000000..68eac812 --- /dev/null +++ b/src/kms/kms_message/kms_kmip_request.h @@ -0,0 +1,58 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_KMIP_REQUEST_H +#define KMS_KMIP_REQUEST_H + +#include "kms_message_defines.h" +#include "kms_request.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define KMS_KMIP_REQUEST_SECRETDATA_LENGTH 96 + +/* kms_kmip_request_register_secretdata_new creates a KMIP Register request with + * a SecretData payload of length KMS_KMIP_REQUEST_SECRETDATA_LENGTH. + * - len must be KMS_KMIP_REQUEST_SECRETDATA_LENGTH. + * - Callers must check for an error by calling kms_request_get_error. */ +KMS_MSG_EXPORT (kms_request_t *) +kms_kmip_request_register_secretdata_new (void *reserved, + const uint8_t *data, + size_t len); + +/* kms_kmip_request_activate_new creates a KMIP Activate request with the + * provided unique identifer. + * - unique_identifier must be a NULL terminated string. + * - Callers must check for an error by calling kms_request_get_error. */ +KMS_MSG_EXPORT (kms_request_t *) +kms_kmip_request_activate_new (void *reserved, const char *unique_identifier); + +/* kms_kmip_request_get_new creates a KMIP Get request with the provided unique + * identifer. + * - unique_identifier must be a NULL terminated string. + * - Callers must check for an error by calling kms_request_get_error. */ +KMS_MSG_EXPORT (kms_request_t *) +kms_kmip_request_get_new (void *reserved, const char *unique_identifier); + +#ifdef __cplusplus +} +#endif + +#endif /* KMS_KMIP_REQUEST_H */ diff --git a/src/kms/kms_message/kms_kmip_response.h b/src/kms/kms_message/kms_kmip_response.h new file mode 100644 index 00000000..4c24c512 --- /dev/null +++ b/src/kms/kms_message/kms_kmip_response.h @@ -0,0 +1,40 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_KMIP_RESPONSE_H +#define KMS_KMIP_RESPONSE_H + +#include "kms_message_defines.h" + +#include + +#include "kms_response.h" + +/* kms_kmip_response_get_unique_identifier returns the UniqueIdentifier in the + * first BatchItem in a ResponseMessage. + * - Returns a NULL terminated string that the caller must free. + * - Returns NULL on error and sets an error on kms_response_t. */ +KMS_MSG_EXPORT (char *) +kms_kmip_response_get_unique_identifier (kms_response_t *res); + +/* kms_kmip_response_get_secretdata returns the KeyMaterial in the + * first BatchItem in a ResponseMessage. + * - Caller must free returned data. + * - Returns NULL on error and sets an error on kms_response_t. */ +KMS_MSG_EXPORT (uint8_t *) +kms_kmip_response_get_secretdata (kms_response_t *res, size_t *secretdatalen); + +#endif /* KMS_KMIP_RESPONSE_H */ diff --git a/src/kms/kms_message/kms_kmip_response_parser.h b/src/kms/kms_message/kms_kmip_response_parser.h new file mode 100644 index 00000000..00257d81 --- /dev/null +++ b/src/kms/kms_message/kms_kmip_response_parser.h @@ -0,0 +1,26 @@ +/* + * Copyright 2021-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KMS_KMIP_RESPONSE_PARSER_H +#define KMS_KMIP_RESPONSE_PARSER_H + +#include "kms_message_defines.h" +#include "kms_response_parser.h" + +KMS_MSG_EXPORT (kms_response_parser_t *) +kms_kmip_response_parser_new (void *reserved); + +#endif /* KMS_KMIP_RESPONSE_PARSER_H */ diff --git a/src/kms/kms_message/kms_message.h b/src/kms/kms_message/kms_message.h index 8048528f..4dc24cdc 100644 --- a/src/kms/kms_message/kms_message.h +++ b/src/kms/kms_message/kms_message.h @@ -20,6 +20,9 @@ #include #include "kms_message_defines.h" +#include "kms_kmip_request.h" +#include "kms_kmip_response.h" +#include "kms_kmip_response_parser.h" #include "kms_request_opt.h" #include "kms_request.h" #include "kms_response.h" diff --git a/src/kms/kms_message/kms_message_defines.h b/src/kms/kms_message/kms_message_defines.h index a539d531..788e1f87 100644 --- a/src/kms/kms_message/kms_message_defines.h +++ b/src/kms/kms_message/kms_message_defines.h @@ -63,4 +63,10 @@ typedef SSIZE_T ssize_t; #pragma warning(default : 4142) #endif +#if defined(_MSC_VER) +#define KMS_MSG_INLINE __inline +#else +#define KMS_MSG_INLINE __inline__ +#endif + #endif /* KMS_MESSAGE_DEFINES_H */ diff --git a/src/kms/kms_message/kms_request.h b/src/kms/kms_message/kms_request.h index cf49f0a3..bda15d45 100644 --- a/src/kms/kms_message/kms_request.h +++ b/src/kms/kms_message/kms_request.h @@ -17,7 +17,8 @@ #ifndef KMS_REQUEST_H #define KMS_REQUEST_H -#include "kms_message.h" +#include "kms_message_defines.h" +#include "kms_request_opt.h" #include #include @@ -28,6 +29,8 @@ extern "C" { #endif +/* A KMS request is general enough to create arbitrary HTTP requests, but also + * supports generating AWS signature v4. */ typedef struct _kms_request_t kms_request_t; KMS_MSG_EXPORT (kms_request_t *) @@ -38,6 +41,8 @@ KMS_MSG_EXPORT (void) kms_request_destroy (kms_request_t *request); KMS_MSG_EXPORT (const char *) kms_request_get_error (kms_request_t *request); + +/* Begin: AWS specific */ KMS_MSG_EXPORT (bool) kms_request_set_date (kms_request_t *request, const struct tm *tm); KMS_MSG_EXPORT (bool) @@ -48,6 +53,8 @@ KMS_MSG_EXPORT (bool) kms_request_set_access_key_id (kms_request_t *request, const char *akid); KMS_MSG_EXPORT (bool) kms_request_set_secret_key (kms_request_t *request, const char *key); +/* End: AWS specific */ + KMS_MSG_EXPORT (bool) kms_request_add_header_field (kms_request_t *request, const char *field_name, @@ -60,6 +67,8 @@ KMS_MSG_EXPORT (bool) kms_request_append_payload (kms_request_t *request, const char *payload, size_t len); + +/* Begin: AWS specific */ KMS_MSG_EXPORT (char *) kms_request_get_canonical (kms_request_t *request); @@ -74,9 +83,19 @@ KMS_MSG_EXPORT (char *) kms_request_get_signature (kms_request_t *request); KMS_MSG_EXPORT (char *) kms_request_get_signed (kms_request_t *request); +/* End: AWS specific */ + KMS_MSG_EXPORT (void) kms_request_free_string (char *ptr); +/* Finalize and obtain a plain HTTP request (no signing). */ +KMS_MSG_EXPORT (char *) kms_request_to_string (kms_request_t *request); + +/* kms_request_to_bytes returns the data for a request. + * - Returns NULL on error and sets an error on request. */ +KMS_MSG_EXPORT (const uint8_t *) +kms_request_to_bytes (kms_request_t *request, size_t *len); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/kms/kms_message/kms_request_opt.h b/src/kms/kms_message/kms_request_opt.h index f38652e9..6a5f70f1 100644 --- a/src/kms/kms_message/kms_request_opt.h +++ b/src/kms/kms_message/kms_request_opt.h @@ -28,13 +28,27 @@ extern "C" { typedef struct _kms_request_opt_t kms_request_opt_t; +typedef size_t kms_request_provider_t; + +#define KMS_REQUEST_PROVIDER_AWS 0 +#define KMS_REQUEST_PROVIDER_AZURE 1 +#define KMS_REQUEST_PROVIDER_GCP 2 +#define KMS_REQUEST_PROVIDER_KMIP 3 + KMS_MSG_EXPORT (kms_request_opt_t *) kms_request_opt_new (void); + +/* The default provider is AWS. This will automatically set extra headers. + * Returns false if provider is invalid. */ +KMS_MSG_EXPORT (bool) +kms_request_opt_set_provider (kms_request_opt_t *opt, + kms_request_provider_t provider); KMS_MSG_EXPORT (void) kms_request_opt_destroy (kms_request_opt_t *request); KMS_MSG_EXPORT (void) kms_request_opt_set_connection_close (kms_request_opt_t *opt, bool connection_close); + KMS_MSG_EXPORT (void) kms_request_opt_set_crypto_hooks (kms_request_opt_t *opt, bool (*sha256) (void *ctx, @@ -49,6 +63,16 @@ kms_request_opt_set_crypto_hooks (kms_request_opt_t *opt, unsigned char *hash_out), void *ctx); +KMS_MSG_EXPORT (void) +kms_request_opt_set_crypto_hook_sign_rsaes_pkcs1_v1_5 ( + kms_request_opt_t *opt, + bool (*sign_rsaes_pkcs1_v1_5) (void *ctx, + const char *private_key, + size_t private_key_len, + const char *input, + size_t input_len, + unsigned char *signature_out), + void *ctx); #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/kms/kms_message/kms_response.h b/src/kms/kms_message/kms_response.h index 545476d4..e58da929 100644 --- a/src/kms/kms_message/kms_response.h +++ b/src/kms/kms_message/kms_response.h @@ -17,7 +17,10 @@ #ifndef KMS_RESPONSE_H #define KMS_RESPONSE_H -#include "kms_message.h" +#include "kms_message_defines.h" + +#include +#include #ifdef __cplusplus extern "C" { @@ -25,9 +28,13 @@ extern "C" { typedef struct _kms_response_t kms_response_t; +KMS_MSG_EXPORT (int) +kms_response_get_status (kms_response_t *response); +KMS_MSG_EXPORT (const char *) +kms_response_get_body (kms_response_t *response, size_t *len); +KMS_MSG_EXPORT (void) kms_response_destroy (kms_response_t *response); KMS_MSG_EXPORT (const char *) -kms_response_get_body (kms_response_t *reply, size_t *len); -KMS_MSG_EXPORT (void) kms_response_destroy (kms_response_t *reply); +kms_response_get_error (const kms_response_t *response); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/kms/kms_message/kms_response_parser.h b/src/kms/kms_message/kms_response_parser.h index c355ff1c..8f134bcf 100644 --- a/src/kms/kms_message/kms_response_parser.h +++ b/src/kms/kms_message/kms_response_parser.h @@ -17,9 +17,13 @@ #ifndef KMS_RESPONSE_PARSER_H #define KMS_RESPONSE_PARSER_H -#include "kms_message.h" +#include "kms_message_defines.h" #include "kms_response.h" +#include +#include +#include + #ifdef __cplusplus extern "C" { #endif @@ -40,6 +44,10 @@ kms_response_parser_feed (kms_response_parser_t *parser, KMS_MSG_EXPORT (kms_response_t *) kms_response_parser_get_response (kms_response_parser_t *parser); +/* kms_response_parser_status returns the HTTP response status if one was + * parsed. + * - Calling on a KMIP parser is an error. + * - Returns an int for the HTTP status or 0 on error. */ KMS_MSG_EXPORT (int) kms_response_parser_status (kms_response_parser_t *parser); diff --git a/src/kms/kms_message_private.h b/src/kms/kms_message_private.h index 6bd3b891..d3fb46b4 100644 --- a/src/kms/kms_message_private.h +++ b/src/kms/kms_message_private.h @@ -23,38 +23,76 @@ #include "kms_request_str.h" #include "kms_kv_list.h" #include "kms_crypto.h" +#include "kms_kmip_response_parser_private.h" + +/* Sadly, Windows does not define SSIZE_MAX. It is defined in bson-compat.h, + * but only since 1.22.x, so copy this from bson-compat.h for now. */ +#ifndef SSIZE_MAX +#define SSIZE_MAX \ + (ssize_t) ( \ + (((size_t) 0x01u) << (sizeof (ssize_t) * (size_t) CHAR_BIT - 1u)) - 1u) +#endif struct _kms_request_t { char error[512]; bool failed; bool finalized; + /* Begin: AWS specific */ kms_request_str_t *region; kms_request_str_t *service; kms_request_str_t *access_key_id; kms_request_str_t *secret_key; + kms_request_str_t *datetime; + kms_request_str_t *date; + /* End: AWS specific */ kms_request_str_t *method; kms_request_str_t *path; kms_request_str_t *query; kms_request_str_t *payload; - kms_request_str_t *datetime; - kms_request_str_t *date; kms_kv_list_t *query_params; kms_kv_list_t *header_fields; /* turn off for tests only, not in public kms_request_opt_t API */ bool auto_content_length; _kms_crypto_t crypto; + kms_request_str_t *to_string; + kms_request_provider_t provider; + + /* TODO (MONGOCRYPT-342): make a union for each KMS provider type. + kms_request_provider_t provider; + union { + struct {} aws; + struct {} azure; + struct {} gcp; + struct {} kmip; + } + */ + struct { + uint8_t *data; + uint32_t len; + } kmip; }; struct _kms_response_t { int status; kms_kv_list_t *headers; kms_request_str_t *body; + + /* TODO (MONGOCRYPT-347): make a union for each KMS provider type. */ + char error[512]; + bool failed; + kms_request_provider_t provider; + struct { + uint8_t *data; + uint32_t len; + } kmip; }; typedef enum { PARSING_STATUS_LINE, PARSING_HEADER, PARSING_BODY, + PARSING_CHUNK_LENGTH, + PARSING_CHUNK, PARSING_DONE } kms_response_parser_state_t; @@ -65,7 +103,18 @@ struct _kms_response_parser_t { kms_request_str_t *raw_response; int content_length; int start; /* start of the current thing getting parsed. */ + + /* Support two types of HTTP 1.1 responses. + * - "Content-Length: x" header is present, indicating the body length. + * - "Transfer-Encoding: chunked" header is present, indicating a stream of + * chunks. + */ + bool transfer_encoding_chunked; + int chunk_size; kms_response_parser_state_t state; + /* TODO: MONGOCRYPT-348 reorganize this struct to better separate fields for + * HTTP parsing and fields for KMIP parsing. */ + kms_kmip_response_parser_t *kmip; }; #define CHECK_FAILED \ @@ -84,10 +133,10 @@ set_error (char *error, size_t size, const char *fmt, ...); set_error (obj->error, sizeof (obj->error), __VA_ARGS__); \ } while (0) -#define KMS_ASSERT(stmt) \ -if (!(stmt)) { \ - fprintf (stderr, "%s failed\n", #stmt); \ - abort (); \ -} +#define KMS_ASSERT(stmt) \ + if (!(stmt)) { \ + fprintf (stderr, "%s failed\n", #stmt); \ + abort (); \ + } #endif /* KMS_MESSAGE_PRIVATE_H */ diff --git a/src/kms/kms_port.c b/src/kms/kms_port.c index 864b5be2..cf5f52f1 100644 --- a/src/kms/kms_port.c +++ b/src/kms/kms_port.c @@ -15,11 +15,9 @@ */ #include "kms_port.h" - +#if defined(_WIN32) #include #include - -#if defined(_WIN32) char * kms_strndup (const char *src, size_t len) { diff --git a/src/kms/kms_port.h b/src/kms/kms_port.h index bc9cef1c..2f2c52fe 100644 --- a/src/kms/kms_port.h +++ b/src/kms/kms_port.h @@ -25,6 +25,8 @@ char * kms_strndup (const char *src, size_t len); #else +#include + #define kms_strndup strndup #define kms_strcasecmp strcasecmp #endif diff --git a/src/kms/kms_request.c b/src/kms/kms_request.c index 10292420..86f90a1a 100644 --- a/src/kms/kms_request.c +++ b/src/kms/kms_request.c @@ -20,6 +20,7 @@ #include "kms_message_private.h" #include "kms_request_opt_private.h" #include "kms_port.h" +#include /* CHAR_BIT */ static kms_kv_list_t * parse_query_params (kms_request_str_t *q) @@ -53,6 +54,16 @@ parse_query_params (kms_request_str_t *q) return lst; } +static bool +check_and_prohibit_kmip (kms_request_t *req) +{ + if (req->provider == KMS_REQUEST_PROVIDER_KMIP) { + KMS_ERROR (req, "Function not applicable to KMIP"); + return false; + } + return true; +} + kms_request_t * kms_request_new (const char *method, const char *path_and_query, @@ -62,6 +73,15 @@ kms_request_new (const char *method, const char *question_mark; KMS_ASSERT (request); + if (opt && opt->provider) { + request->provider = opt->provider; + } else { + request->provider = KMS_REQUEST_PROVIDER_AWS; + } + + if (!check_and_prohibit_kmip (request)) { + return request; + } /* parsing may set failed to true */ request->failed = false; @@ -93,7 +113,9 @@ kms_request_new (const char *method, request->header_fields = kms_kv_list_new (); request->auto_content_length = true; - if (!kms_request_set_date (request, NULL)) { + /* For AWS KMS requests, add a X-Amz-Date header. */ + if (request->provider == KMS_REQUEST_PROVIDER_AWS && + !kms_request_set_date (request, NULL)) { return request; } @@ -128,6 +150,8 @@ kms_request_destroy (kms_request_t *request) kms_request_str_destroy (request->date); kms_kv_list_destroy (request->query_params); kms_kv_list_destroy (request->header_fields); + kms_request_str_destroy (request->to_string); + free (request->kmip.data); free (request); } @@ -149,14 +173,20 @@ kms_request_set_date (kms_request_t *request, const struct tm *tm) return false; } + if (!check_and_prohibit_kmip (request)) { + return false; + } + if (!tm) { /* use current time */ time_t t; time (&t); -#ifdef _WIN32 +#if defined(KMS_MESSAGE_HAVE_GMTIME_R) + gmtime_r (&t, &tmp_tm); +#elif defined(_MSC_VER) gmtime_s (&tmp_tm, &t); #else - gmtime_r (&t, &tmp_tm); + tmp_tm = *gmtime (&t); #endif tm = &tmp_tm; } @@ -181,6 +211,9 @@ kms_request_set_date (kms_request_t *request, const struct tm *tm) bool kms_request_set_region (kms_request_t *request, const char *region) { + if (!check_and_prohibit_kmip (request)) { + return false; + } kms_request_str_set_chars (request->region, region, -1); return true; } @@ -188,6 +221,9 @@ kms_request_set_region (kms_request_t *request, const char *region) bool kms_request_set_service (kms_request_t *request, const char *service) { + if (!check_and_prohibit_kmip (request)) { + return false; + } kms_request_str_set_chars (request->service, service, -1); return true; } @@ -195,6 +231,9 @@ kms_request_set_service (kms_request_t *request, const char *service) bool kms_request_set_access_key_id (kms_request_t *request, const char *akid) { + if (!check_and_prohibit_kmip (request)) { + return false; + } kms_request_str_set_chars (request->access_key_id, akid, -1); return true; } @@ -202,6 +241,9 @@ kms_request_set_access_key_id (kms_request_t *request, const char *akid) bool kms_request_set_secret_key (kms_request_t *request, const char *key) { + if (!check_and_prohibit_kmip (request)) { + return false; + } kms_request_str_set_chars (request->secret_key, key, -1); return true; } @@ -215,6 +257,10 @@ kms_request_add_header_field (kms_request_t *request, CHECK_FAILED; + if (!check_and_prohibit_kmip (request)) { + return false; + } + k = kms_request_str_new_from_chars (field_name, -1); v = kms_request_str_new_from_chars (value, -1); kms_kv_list_add (request->header_fields, k, v); @@ -233,6 +279,10 @@ kms_request_append_header_field_value (kms_request_t *request, CHECK_FAILED; + if (!check_and_prohibit_kmip (request)) { + return false; + } + if (request->header_fields->len == 0) { KMS_ERROR ( request, @@ -241,7 +291,8 @@ kms_request_append_header_field_value (kms_request_t *request, } v = request->header_fields->kvs[request->header_fields->len - 1].value; - kms_request_str_append_chars (v, value, len); + KMS_ASSERT (len <= SSIZE_MAX); + kms_request_str_append_chars (v, value, (ssize_t) len); return true; } @@ -253,7 +304,12 @@ kms_request_append_payload (kms_request_t *request, { CHECK_FAILED; - kms_request_str_append_chars (request->payload, payload, len); + if (!check_and_prohibit_kmip (request)) { + return false; + } + + KMS_ASSERT (len <= SSIZE_MAX); + kms_request_str_append_chars (request->payload, payload, (ssize_t) len); return true; } @@ -385,10 +441,13 @@ finalize (kms_request_t *request) lst = request->header_fields; - /* By default, if no explicit Host was set, it is derived from region + - * service */ if (!kms_kv_list_find (lst, "Host")) { - /* like "kms.us-east-1.amazonaws.com" */ + if (request->provider != KMS_REQUEST_PROVIDER_AWS) { + KMS_ERROR (request, "Required Host header not set"); + return false; + } + /* For AWS requests, derive a default Host header from region + service. + * E.g. "kms.us-east-1.amazonaws.com" */ k = kms_request_str_new_from_chars ("Host", -1); v = kms_request_str_dup (request->service); kms_request_str_append_char (v, '.'); @@ -448,6 +507,10 @@ kms_request_get_canonical (kms_request_t *request) return NULL; } + if (!check_and_prohibit_kmip (request)) { + return NULL; + } + if (!finalize (request)) { return NULL; } @@ -486,6 +549,10 @@ kms_request_get_canonical_header (kms_request_t *request, const char *header) return NULL; } + if (!check_and_prohibit_kmip (request)) { + return NULL; + } + if (!finalize (request)) { return NULL; } @@ -509,6 +576,10 @@ kms_request_get_string_to_sign (kms_request_t *request) return NULL; } + if (!check_and_prohibit_kmip (request)) { + return NULL; + } + if (!finalize (request)) { return NULL; } @@ -553,7 +624,7 @@ kms_request_hmac (_kms_crypto_t *crypto, kms_request_str_t *data) { return crypto->sha256_hmac ( - crypto->ctx, key->str, (int) key->len, data->str, data->len, out); + crypto->ctx, key->str, key->len, data->str, data->len, out); } static bool @@ -580,6 +651,10 @@ kms_request_get_signing_key (kms_request_t *request, unsigned char *key) return false; } + if (!check_and_prohibit_kmip (request)) { + return false; + } + /* docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html * Pseudocode for deriving a signing key * @@ -627,6 +702,10 @@ kms_request_get_signature (kms_request_t *request) return NULL; } + if (!check_and_prohibit_kmip (request)) { + return NULL; + } + sts = kms_request_str_wrap (kms_request_get_string_to_sign (request), -1); if (!sts) { goto done; @@ -668,6 +747,9 @@ kms_request_get_signature (kms_request_t *request) void kms_request_validate (kms_request_t *request) { + if (!check_and_prohibit_kmip (request)) { + return; + } if (0 == request->region->len) { KMS_ERROR (request, "Region not set"); } else if (0 == request->service->len) { @@ -685,6 +767,13 @@ kms_request_validate (kms_request_t *request) } } +/* append_http_endofline appends an HTTP end-of-line marker: "\r\n". */ +static void +append_http_endofline (kms_request_str_t *str) +{ + kms_request_str_append_chars (str, "\r\n", 2); +} + char * kms_request_get_signed (kms_request_t *request) { @@ -699,6 +788,10 @@ kms_request_get_signed (kms_request_t *request) return NULL; } + if (!check_and_prohibit_kmip (request)) { + return false; + } + if (!finalize (request)) { return NULL; } @@ -714,7 +807,7 @@ kms_request_get_signed (kms_request_t *request) } kms_request_str_append_chars (sreq, " HTTP/1.1", -1); - kms_request_str_append_newline (sreq); + append_http_endofline (sreq); /* headers */ lst = kms_kv_list_dup (request->header_fields); @@ -723,7 +816,7 @@ kms_request_get_signed (kms_request_t *request) kms_request_str_append (sreq, lst->kvs[i].key); kms_request_str_append_char (sreq, ':'); kms_request_str_append (sreq, lst->kvs[i].value); - kms_request_str_append_newline (sreq); + append_http_endofline (sreq); } /* authorization header */ @@ -738,8 +831,8 @@ kms_request_get_signed (kms_request_t *request) /* body */ if (request->payload->len) { - kms_request_str_append_newline (sreq); - kms_request_str_append_newline (sreq); + append_http_endofline (sreq); + append_http_endofline (sreq); kms_request_str_append (sreq, request->payload); } @@ -756,8 +849,79 @@ kms_request_get_signed (kms_request_t *request) return kms_request_str_detach (sreq); } +char * +kms_request_to_string (kms_request_t *request) +{ + kms_kv_list_t *lst = NULL; + kms_request_str_t *sreq = NULL; + size_t i; + + if (!finalize (request)) { + return false; + } + + if (!check_and_prohibit_kmip (request)) { + return false; + } + + if (request->to_string) { + return kms_request_str_detach (kms_request_str_dup (request->to_string)); + } + + sreq = kms_request_str_new (); + /* like "POST / HTTP/1.1" */ + kms_request_str_append (sreq, request->method); + kms_request_str_append_char (sreq, ' '); + kms_request_str_append (sreq, request->path); + if (request->query->len) { + kms_request_str_append_char (sreq, '?'); + kms_request_str_append (sreq, request->query); + } + + kms_request_str_append_chars (sreq, " HTTP/1.1", -1); + append_http_endofline (sreq); + + /* headers */ + lst = kms_kv_list_dup (request->header_fields); + kms_kv_list_sort (lst, cmp_header_field_names); + for (i = 0; i < lst->len; i++) { + kms_request_str_append (sreq, lst->kvs[i].key); + kms_request_str_append_char (sreq, ':'); + kms_request_str_append (sreq, lst->kvs[i].value); + append_http_endofline (sreq); + } + + append_http_endofline (sreq); + + /* body */ + if (request->payload->len) { + kms_request_str_append (sreq, request->payload); + } + + kms_kv_list_destroy (lst); + request->to_string = kms_request_str_dup (sreq); + return kms_request_str_detach (sreq); +} + void kms_request_free_string (char *ptr) { free (ptr); } + +const uint8_t * +kms_request_to_bytes (kms_request_t *request, size_t *len) +{ + if (request->provider == KMS_REQUEST_PROVIDER_KMIP) { + *len = request->kmip.len; + return request->kmip.data; + } + + if (!request->to_string && !kms_request_to_string (request)) { + return NULL; + } + + KMS_ASSERT (request->to_string); + *len = request->to_string->len; + return (const uint8_t*) request->to_string->str; +} diff --git a/src/kms/kms_request_opt.c b/src/kms/kms_request_opt.c index 9bbc43a4..c9e1b00a 100644 --- a/src/kms/kms_request_opt.c +++ b/src/kms/kms_request_opt.c @@ -57,3 +57,32 @@ kms_request_opt_set_crypto_hooks (kms_request_opt_t *opt, opt->crypto.sha256_hmac = sha256_hmac; opt->crypto.ctx = ctx; } + +bool +kms_request_opt_set_provider (kms_request_opt_t *opt, + kms_request_provider_t provider) +{ + if (provider != KMS_REQUEST_PROVIDER_AWS && + provider != KMS_REQUEST_PROVIDER_AZURE && + provider != KMS_REQUEST_PROVIDER_GCP && + provider != KMS_REQUEST_PROVIDER_KMIP) { + return false; + } + opt->provider = provider; + return true; +} + +void +kms_request_opt_set_crypto_hook_sign_rsaes_pkcs1_v1_5 ( + kms_request_opt_t *opt, + bool (*sign_rsaes_pkcs1_v1_5) (void *sign_ctx, + const char *private_key, + size_t private_key_len, + const char *input, + size_t input_len, + unsigned char *signature_out), + void *sign_ctx) +{ + opt->crypto.sign_rsaes_pkcs1_v1_5 = sign_rsaes_pkcs1_v1_5; + opt->crypto.sign_ctx = sign_ctx; +} \ No newline at end of file diff --git a/src/kms/kms_request_opt_private.h b/src/kms/kms_request_opt_private.h index 5e971a9d..8c25bdf2 100644 --- a/src/kms/kms_request_opt_private.h +++ b/src/kms/kms_request_opt_private.h @@ -26,6 +26,7 @@ struct _kms_request_opt_t { bool connection_close; _kms_crypto_t crypto; + kms_request_provider_t provider; }; #endif /* KMS_REQUEST_OPT_PRIVATE_H */ diff --git a/src/kms/kms_request_str.c b/src/kms/kms_request_str.c index dec16efb..23f33cd4 100644 --- a/src/kms/kms_request_str.c +++ b/src/kms/kms_request_str.c @@ -25,6 +25,7 @@ #include #include #include +#include /* CHAR_BIT */ bool rfc_3986_tab[256] = {0}; bool kms_initialized = false; @@ -216,12 +217,15 @@ kms_request_str_append_chars (kms_request_str_t *str, const char *appended, ssize_t len) { + size_t str_len; if (len < 0) { - len = strlen (appended); + str_len = strlen (appended); + } else { + str_len = (size_t) len; } - kms_request_str_reserve (str, (size_t) len); - memcpy (str->str + str->len, appended, (size_t) len); - str->len += len; + kms_request_str_reserve (str, str_len); + memcpy (str->str + str->len, appended, str_len); + str->len += str_len; str->str[str->len] = '\0'; } @@ -245,7 +249,7 @@ kms_request_str_append_lowercase (kms_request_str_t *str, for (; i < str->len; ++i) { p = &str->str[i]; /* ignore UTF-8 non-ASCII chars, which have 1 in the top bit */ - if ((*p & (0x1U << 7U)) == 0) { + if (((unsigned int) (*p) & (0x1U << 7U)) == 0) { *p = (char) tolower (*p); } } @@ -384,7 +388,8 @@ kms_request_str_append_hex (kms_request_str_t *str, char *hex_chars; hex_chars = hexlify (data, len); - kms_request_str_append_chars (str, hex_chars, len * 2); + KMS_ASSERT (len <= SSIZE_MAX / 2); + kms_request_str_append_chars (str, hex_chars, (ssize_t) (len * 2)); free (hex_chars); return true; @@ -410,7 +415,8 @@ delete_last_segment (kms_request_str_t *str, bool is_absolute) return; } - for (i = str->len - 1; i >= 0; --i) { + KMS_ASSERT (str->len < SSIZE_MAX); + for (i = (ssize_t) str->len - 1; i >= 0; --i) { if (str->str[i] == '/') { if (i == 0 && is_absolute) { str->len = 1; diff --git a/src/kms/kms_request_str.h b/src/kms/kms_request_str.h index 0898f590..4e33faa1 100644 --- a/src/kms/kms_request_str.h +++ b/src/kms/kms_request_str.h @@ -67,6 +67,8 @@ kms_request_str_append_lowercase (kms_request_str_t *str, KMS_MSG_EXPORT (void) kms_request_str_appendf (kms_request_str_t *str, const char *format, ...); KMS_MSG_EXPORT (void) +kms_request_strdupf (kms_request_str_t *str, const char *format, ...); +KMS_MSG_EXPORT (void) kms_request_str_append_escaped (kms_request_str_t *str, kms_request_str_t *appended, bool escape_slash); diff --git a/src/kms/kms_response.c b/src/kms/kms_response.c index dc994e93..85e333c5 100644 --- a/src/kms/kms_response.c +++ b/src/kms/kms_response.c @@ -25,6 +25,8 @@ kms_response_destroy (kms_response_t *response) if (response == NULL) { return; } + + free (response->kmip.data); kms_kv_list_destroy (response->headers); kms_request_str_destroy (response->body); free (response); @@ -38,3 +40,15 @@ kms_response_get_body (kms_response_t *response, size_t *len) } return response->body->str; } + +int +kms_response_get_status (kms_response_t *response) +{ + return response->status; +} + +const char * +kms_response_get_error (const kms_response_t *response) +{ + return response->failed ? response->error : NULL; +} diff --git a/src/kms/kms_response_parser.c b/src/kms/kms_response_parser.c index 6f86fac8..4d2e7a12 100644 --- a/src/kms/kms_response_parser.c +++ b/src/kms/kms_response_parser.c @@ -1,11 +1,14 @@ #include "kms_message/kms_response_parser.h" #include "kms_message_private.h" +#include "kms_kmip_response_parser_private.h" #include #include #include #include +#include "hexlify.h" + /* destroys the members of parser, but not the parser itself. */ static void _parser_destroy (kms_response_parser_t *parser) @@ -15,6 +18,7 @@ _parser_destroy (kms_response_parser_t *parser) parser->content_length = -1; kms_response_destroy (parser->response); parser->response = NULL; + kms_kmip_response_parser_destroy (parser->kmip); } /* initializes the members of parser. */ @@ -29,6 +33,9 @@ _parser_init (kms_response_parser_t *parser) parser->state = PARSING_STATUS_LINE; parser->start = 0; parser->failed = false; + parser->chunk_size = 0; + parser->transfer_encoding_chunked = false; + parser->kmip = NULL; } kms_response_parser_t * @@ -44,16 +51,27 @@ kms_response_parser_new (void) int kms_response_parser_wants_bytes (kms_response_parser_t *parser, int32_t max) { + if (parser->kmip) { + return kms_kmip_response_parser_wants_bytes (parser->kmip, max); + } switch (parser->state) { case PARSING_DONE: return 0; case PARSING_STATUS_LINE: case PARSING_HEADER: return max; + case PARSING_CHUNK_LENGTH: + return max; + case PARSING_CHUNK: + /* add 2 for trailing \r\n */ + return (parser->chunk_size + 2) - + ((int) parser->raw_response->len - parser->start); case PARSING_BODY: KMS_ASSERT (parser->content_length != -1); return parser->content_length - ((int) parser->raw_response->len - parser->start); + default: + KMS_ASSERT (false && "Invalid kms_response_parser HTTP state"); } return -1; } @@ -89,18 +107,30 @@ _parse_int (const char *str, int *result) static bool _parse_int_from_view (const char *str, int start, int end, int *result) { - char *num_str = malloc (end - start + 1); + KMS_ASSERT (end >= start); + char *num_str = malloc ((size_t) (end - start + 1)); KMS_ASSERT (num_str); bool ret; - strncpy (num_str, str + start, end - start); + strncpy (num_str, str + start, (size_t) (end - start)); num_str[end - start] = '\0'; ret = _parse_int (num_str, result); free (num_str); return ret; } +static bool +_parse_hex_from_view (const char *str, int len, int *result) +{ + KMS_ASSERT (len >= 0); + *result = unhexlify (str, (size_t) len); + if (*result < 0) { + return false; + } + return true; +} + /* returns true if char is "linear white space". This *ignores* the folding case * of CRLF followed by WSP. See https://stackoverflow.com/a/21072806/774658 */ static bool @@ -154,6 +184,9 @@ _parse_line (kms_response_parser_t *parser, int end) if (i == end) { /* empty line, this signals the start of the body. */ + if (parser->transfer_encoding_chunked) { + return PARSING_CHUNK_LENGTH; + } return PARSING_BODY; } @@ -201,9 +234,29 @@ _parse_line (kms_response_parser_t *parser, int end) return PARSING_DONE; } } + + if (0 == strcmp (key->str, "Transfer-Encoding")) { + if (0 == strcmp (val->str, "chunked")) { + parser->transfer_encoding_chunked = true; + } else { + KMS_ERROR (parser, "Unsupported Transfer-Encoding: %s", val->str); + kms_request_str_destroy (key); + kms_request_str_destroy (val); + return PARSING_DONE; + } + } kms_request_str_destroy (key); kms_request_str_destroy (val); return PARSING_HEADER; + } else if (parser->state == PARSING_CHUNK_LENGTH) { + int result = 0; + + if (!_parse_hex_from_view (raw + i, end - i, &result)) { + KMS_ERROR (parser, "Failed to parse hex chunk length."); + return PARSING_DONE; + } + parser->chunk_size = result; + return PARSING_CHUNK; } return PARSING_DONE; } @@ -214,7 +267,11 @@ kms_response_parser_feed (kms_response_parser_t *parser, uint32_t len) { kms_request_str_t *raw = parser->raw_response; - int curr, body_read; + int curr, body_read, chunk_read; + + if (parser->kmip) { + return kms_kmip_response_parser_feed (parser->kmip, buf, len); + } curr = (int) raw->len; kms_request_str_append_chars (raw, (char *) buf, len); @@ -223,6 +280,7 @@ kms_response_parser_feed (kms_response_parser_t *parser, switch (parser->state) { case PARSING_STATUS_LINE: case PARSING_HEADER: + case PARSING_CHUNK_LENGTH: /* find the next \r\n. */ if (curr && strncmp (raw->str + (curr - 1), "\r\n", 2) == 0) { parser->state = _parse_line (parser, curr - 1); @@ -254,9 +312,33 @@ kms_response_parser_feed (kms_response_parser_t *parser, curr = (int) raw->len; break; + case PARSING_CHUNK: + chunk_read = (int) raw->len - parser->start; + /* check if we've read the full chunk and the trailing \r\n */ + if (chunk_read >= parser->chunk_size + 2) { + if (!parser->response->body) { + parser->response->body = kms_request_str_new (); + } + kms_request_str_append_chars (parser->response->body, + raw->str + parser->start, + parser->chunk_size); + curr = parser->start + parser->chunk_size + 2; + parser->start = curr; + if (parser->chunk_size == 0) { + /* last chunk. */ + parser->state = PARSING_DONE; + } else { + parser->state = PARSING_CHUNK_LENGTH; + } + } else { + curr = (int) raw->len; + } + break; case PARSING_DONE: KMS_ERROR (parser, "Unexpected extra HTTP content"); return false; + default: + KMS_ASSERT (false && "Invalid kms_response_parser HTTP state"); } } @@ -270,7 +352,13 @@ kms_response_parser_feed (kms_response_parser_t *parser, kms_response_t * kms_response_parser_get_response (kms_response_parser_t *parser) { - kms_response_t *response = parser->response; + kms_response_t *response; + + if (parser->kmip) { + return kms_kmip_response_parser_get_response (parser->kmip); + } + + response = parser->response; parser->response = NULL; /* reset the parser. */ @@ -282,7 +370,16 @@ kms_response_parser_get_response (kms_response_parser_t *parser) int kms_response_parser_status (kms_response_parser_t *parser) { - if (!parser || !(parser->response)) { + if (!parser) { + return 0; + } + + if (parser->kmip) { + KMS_ERROR (parser, "kms_response_parser_status not applicable to KMIP"); + return 0; + } + + if (!parser->response) { return 0; } @@ -296,6 +393,10 @@ kms_response_parser_error (kms_response_parser_t *parser) return NULL; } + if (parser->kmip) { + return kms_kmip_response_parser_error (parser->kmip); + } + return parser->error; } diff --git a/src/mongoc/mcd-azure.c b/src/mongoc/mcd-azure.c new file mode 100644 index 00000000..8f51351f --- /dev/null +++ b/src/mongoc/mcd-azure.c @@ -0,0 +1,210 @@ +/** + * Copyright 2022 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "./mcd-azure.h" + +#include "mongoc-util-private.h" + +#define AZURE_API_VERSION "2018-02-01" + +static const char *const DEFAULT_METADATA_PATH = + "/metadata/identity/oauth2/" + "token?api-version=" AZURE_API_VERSION + "&resource=https%3A%2F%2Fvault.azure.net"; + +void +mcd_azure_imds_request_init (mcd_azure_imds_request *req, + const char *const opt_imds_host, + int opt_port, + const char *const opt_extra_headers) +{ + BSON_ASSERT_PARAM (req); + _mongoc_http_request_init (&req->req); + // The HTTP host of the IMDS server + req->req.host = req->_owned_host = + bson_strdup (opt_imds_host ? opt_imds_host : "169.254.169.254"); + if (opt_port) { + req->req.port = opt_port; + } else { + req->req.port = 80; + } + // No body + req->req.body = ""; + // We GET + req->req.method = "GET"; + // 'Metadata: true' is required + req->req.extra_headers = req->_owned_headers = + bson_strdup_printf ("Metadata: true\r\n" + "Accept: application/json\r\n%s", + opt_extra_headers ? opt_extra_headers : ""); + // The default path is suitable. In the future, we may want to add query + // parameters to disambiguate a managed identity. + req->req.path = req->_owned_path = bson_strdup (DEFAULT_METADATA_PATH); +} + +void +mcd_azure_imds_request_destroy (mcd_azure_imds_request *req) +{ + BSON_ASSERT_PARAM (req); + bson_free (req->_owned_path); + bson_free (req->_owned_host); + bson_free (req->_owned_headers); + *req = MCD_AZURE_IMDS_REQUEST_INIT; +} + +bool +mcd_azure_access_token_try_init_from_json_str (mcd_azure_access_token *out, + const char *json, + int len, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (out); + BSON_ASSERT_PARAM (json); + bool okay = false; + + if (len < 0) { + // Detect from a null-terminated string + len = (int) strlen (json); + } + + // Zero the output + *out = (mcd_azure_access_token){0}; + + // Parse the JSON data + bson_t bson; + if (!bson_init_from_json (&bson, json, len, error)) { + return false; + } + + bson_iter_t iter; + // access_token + bool found = bson_iter_init_find (&iter, &bson, "access_token"); + const char *const access_token = + !found ? NULL : bson_iter_utf8 (&iter, NULL); + // resource + found = bson_iter_init_find (&iter, &bson, "resource"); + const char *const resource = !found ? NULL : bson_iter_utf8 (&iter, NULL); + // token_type + found = bson_iter_init_find (&iter, &bson, "token_type"); + const char *const token_type = !found ? NULL : bson_iter_utf8 (&iter, NULL); + // expires_in + found = bson_iter_init_find (&iter, &bson, "expires_in"); + uint32_t expires_in_len = 0; + const char *const expires_in_str = + !found ? NULL : bson_iter_utf8 (&iter, &expires_in_len); + + if (!(access_token && resource && token_type && expires_in_str)) { + bson_set_error ( + error, + MONGOC_ERROR_AZURE, + MONGOC_ERROR_KMS_SERVER_BAD_JSON, + "One or more required JSON properties are missing/invalid: data: %.*s", + len, + json); + } else { + // Set the output, duplicate each string + *out = (mcd_azure_access_token){ + .access_token = bson_strdup (access_token), + .resource = bson_strdup (resource), + .token_type = bson_strdup (token_type), + }; + // "expires_in" encodes the number of seconds since the issue time for + // which the token will be valid. strtoll() will saturate on range errors + // and return zero on parse errors. + char *parse_end; + long long s = strtoll (expires_in_str, &parse_end, 0); + if (parse_end != expires_in_str + expires_in_len) { + // Did not parse the entire string. Bad + bson_set_error ( + error, + MONGOC_ERROR_AZURE, + MONGOC_ERROR_KMS_SERVER_BAD_JSON, + "Invalid 'expires_in' string \"%.*s\" from IMDS server", + expires_in_len, + expires_in_str); + } else { + out->expires_in = mcd_seconds (s); + okay = true; + } + } + + bson_destroy (&bson); + return okay; +} + + +void +mcd_azure_access_token_destroy (mcd_azure_access_token *c) +{ + bson_free (c->access_token); + bson_free (c->resource); + bson_free (c->token_type); + c->access_token = NULL; + c->resource = NULL; + c->token_type = NULL; +} + + +bool +mcd_azure_access_token_from_imds (mcd_azure_access_token *const out, + const char *const opt_imds_host, + int opt_port, + const char *opt_extra_headers, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (out); + + bool okay = false; + + // Clear the output + *out = (mcd_azure_access_token){0}; + + mongoc_http_response_t resp; + _mongoc_http_response_init (&resp); + + mcd_azure_imds_request req = MCD_AZURE_IMDS_REQUEST_INIT; + mcd_azure_imds_request_init ( + &req, opt_imds_host, opt_port, opt_extra_headers); + + if (!_mongoc_http_send (&req.req, 3 * 1000, false, NULL, &resp, error)) { + goto fail; + } + + // We only accept an HTTP 200 as a success + if (resp.status != 200) { + bson_set_error (error, + MONGOC_ERROR_AZURE, + MONGOC_ERROR_KMS_SERVER_HTTP, + "Error from Azure IMDS server while looking for " + "Managed Identity access token: %.*s", + resp.body_len, + resp.body); + goto fail; + } + + // Parse the token from the response JSON + if (!mcd_azure_access_token_try_init_from_json_str ( + out, resp.body, resp.body_len, error)) { + goto fail; + } + + okay = true; + +fail: + mcd_azure_imds_request_destroy (&req); + _mongoc_http_response_cleanup (&resp); + return okay; +} diff --git a/src/mongoc/mcd-azure.h b/src/mongoc/mcd-azure.h new file mode 100644 index 00000000..54120ddc --- /dev/null +++ b/src/mongoc/mcd-azure.h @@ -0,0 +1,137 @@ +/** + * Copyright 2022 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MCD_AZURE_H_INCLUDED +#define MCD_AZURE_H_INCLUDED + +#include "mongoc-prelude.h" + +#include + +#include + +#include + +/** + * @brief An Azure OAuth2 access token obtained from the Azure API + */ +typedef struct mcd_azure_access_token { + /// The access token string + char *access_token; + /// The resource of the token (the Azure resource for which it is valid) + char *resource; + /// The HTTP type of the token + char *token_type; + /// The duration after which it will the token will expires. This is relative + /// to the "issue time" of the token. + mcd_duration expires_in; +} mcd_azure_access_token; + +/** + * @brief Try to parse an Azure access token from an IMDS metadata JSON response + * + * @param out The token to initialize. Should be uninitialized. Must later be + * destroyed by the caller. + * @param json The JSON string body + * @param len The length of 'body' + * @param error An output parameter for errors + * @retval true If 'out' was successfully initialized to a token. + * @retval false Otherwise + * + * @note The 'out' token must later be given to @ref + * mcd_azure_access_token_destroy + */ +bool +mcd_azure_access_token_try_init_from_json_str (mcd_azure_access_token *out, + const char *json, + int len, + bson_error_t *error) + BSON_GNUC_WARN_UNUSED_RESULT; + +/** + * @brief Destroy and zero-fill an access token object + * + * @param token The access token to destroy + */ +void +mcd_azure_access_token_destroy (mcd_azure_access_token *token); + +/** + * @brief An Azure IMDS HTTP request + */ +typedef struct mcd_azure_imds_request { + /// The underlying HTTP request object to be sent + mongoc_http_request_t req; + char *_owned_path; + char *_owned_host; + char *_owned_headers; +} mcd_azure_imds_request; + +#define MCD_AZURE_IMDS_REQUEST_INIT \ + (mcd_azure_imds_request) \ + { \ + .req = {0}, ._owned_path = NULL, ._owned_host = NULL, \ + ._owned_headers = NULL, \ + } + +/** + * @brief Initialize a new IMDS HTTP request + * + * @param out The object to initialize + * @param opt_imds_host (Optional) the IP host of the IMDS server + * @param opt_port (Optional) The port of the IMDS HTTP server (default is 80) + * @param opt_extra_headers (Optional) Set extra HTTP headers for the request + * + * @note the request must later be destroyed with mcd_azure_imds_request_destroy + * @note Currently only supports the vault.azure.net resource + */ +void +mcd_azure_imds_request_init (mcd_azure_imds_request *req, + const char *const opt_imds_host, + int opt_port, + const char *const opt_extra_headers); + +/** + * @brief Destroy an IMDS request created with mcd_azure_imds_request_init() + * + * @param req + */ +void +mcd_azure_imds_request_destroy (mcd_azure_imds_request *req); + +/** + * @brief Attempt to obtain a new OAuth2 access token from an Azure IMDS HTTP + * server. + * + * @param out The output parameter for the obtained token. Must later be + * destroyed + * @param opt_imds_host (Optional) Override the IP host of the IMDS server + * @param opt_port (Optional) The port of the IMDS HTTP server (default is 80) + * @param opt_extra_headers (Optional) Set extra HTTP headers for the request + * @param error Output parameter for errors + * @retval true Upon success + * @retval false Otherwise. Sets an error via `error` + * + * @note Currently only supports the vault.azure.net resource + */ +bool +mcd_azure_access_token_from_imds (mcd_azure_access_token *const out, + const char *const opt_imds_host, + int opt_port, + const char *opt_extra_headers, + bson_error_t *error); + +#endif // MCD_AZURE_H_INCLUDED diff --git a/src/mongoc/mcd-integer.h b/src/mongoc/mcd-integer.h new file mode 100644 index 00000000..b4eedc26 --- /dev/null +++ b/src/mongoc/mcd-integer.h @@ -0,0 +1,390 @@ +/** + * Copyright 2022 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MCD_INTEGER_H_INCLUDED +#define MCD_INTEGER_H_INCLUDED + +#include "mongoc-prelude.h" + +#include + +#include +#include + +/// Return 'true' iff (left * right) would overflow with int64 +static BSON_INLINE bool +_mcd_i64_mul_would_overflow (int64_t left, int64_t right) +{ + if (right == -1) { + // We will perform an integer division, and only (MIN / -1) is undefined + // for integer division. + return left == INT64_MIN; + } + + if (right == 0) { + // Multiplication by zero never overflows, and we cannot divide by zero + return false; + } + + // From here on, all integer division by 'right' is well-defined + + if (left > 0) { + if (right > 0) { + /** + Given: left > 0 + and: right > 0 + then: left * right > 0 + THEN: left * right > MIN + + Define: max_fac = MAX / right + then: max_fac * right = (MAX / right) * right + then: max_fac * right = MAX + */ + const int64_t max_fac = INT64_MAX / right; + if (left > max_fac) { + /** + Given: left > max_fac + then: left * right > max_fac * right + with: MAX = max_fac * right + then: left * right > MAX + */ + return true; + } else { + /** + Given: left <= max_fac + then: left * right <= max_fac * right + with: MAX = max_fac * right + THEN: left * right <= MAX + */ + return false; + } + } else { + /** + Given: left > 0 + and: right <= 0 + then: left * right < 0 + THEN: left * right < MAX + + Define: min_fac = MIN / left + then: min_Fac * left = (MIN / left) * left + then: min_Fac * left = MIN + */ + const int64_t min_fac = INT64_MIN / left; + if (right < min_fac) { + /** + Given: right < min_fac + then: right * left < min_fac * left + with: min_fac * left = MIN + then: right * left < MIN + */ + return true; + } else { + /** + Given: right >= min_fac + then: right * left >= min_fac * left + with: min_fac * left = MIN + then: right * left >= MIN + */ + return false; + } + } + } else { + if (right > 0) { + /** + Given: left <= 0 + and: right > 0 + then: left * right <= 0 + THEN: left * right < MAX + + Define: min_fac = MIN / right + then: min_fac * right = (MIN / right) * right + then: min_fac * right = MIN + */ + const int64_t min_fac = INT64_MIN / right; + if (left < min_fac) { + /** + Given: left < min_fac + then: left * right < min_fac * right + with: MIN = min_fac * right + then: left * right < MIN + */ + return true; + } else { + /** + Given: left >= min_fac + then: left * right >= min_fac * right + with: MIN = min_fac * right + then: left * right >= MIN + */ + return false; + } + } else { + /** + Given: left <= 0 + and: right <= 0 + then: left * right >= 0 + THEN: left * right > MIN + */ + if (left == 0) { + // Multiplication by zero will never overflow + return false; + } else { + /** + Given: left <= 0 + and: left != 0 + then: left < 0 + + Define: max_fac = MAX / left + then: max_fac * left = (MAX / left) * left + then: max_fac * left = MAX + + Given: left < 0 + and: MAX > 0 + and: max_fac = MAX / left + then: max_fac < 0 [pos/neg -> neg] + */ + const int64_t max_fac = INT64_MAX / left; + if (right < max_fac) { + /* + Given: right < max_fac + and: left < 0 + then: left * right > max_fac * left + then: left * right > (MAX / left) * left + then: left * right > MAX + */ + return true; + } else { + /* + Given: right >= max_fac + and: left < 0 + then: left * right <= max_fac * left + then: left * right <= (MAX / left) * left + then: left * right <= MAX + */ + return false; + } + } + } + } +} + +/// Return 'true' iff (left + right) would overflow with int64 +static BSON_INLINE bool +_mcd_i64_add_would_overflow (int64_t left, int64_t right) +{ + /** + * Context: + * + * - MAX, MIN, left: right: ℤ + * - left >= MIN + * - left <= MAX + * - right >= MIN + * - right <= MAX + * - forall (N, M, Q : ℤ) . + * if N = M then + * M = N (Symmetry) + * N + 0 = N (Zero is neutral) + * N + M = M + N (Addition is commutative) + * if N < M then + * 0 - N > 0 - M (Order inversion) + * M > N (Symmetry inversion) + * 0 - M < 0 - N (order+symmetry inversion) + * if M < Q or M = Q then + * N < Q (Order transitivity) + * 0 - M = -M (Negation is subtraction) + * N - M = N + (-M) + * Ord(N, M) = Ord(N+Q, M+Q) (Addition preserves ordering) + */ + // MAX, MIN, left, right: ℤ + //* Given: right <= MAX + //* Given: left <= MAX + + if (right < 0) { + /** + Given: right < 0 + then: left + right < left + 0 + then: left + right < left + then: left + right <= left [Weakening] + + Given: left <= MAX + and: left + right <= left + then: left + right <= MAX + THEN: left + right CANNOT overflow MAX + */ + + /** + Given: right >= MIN + then: 0 - right <= 0 - MIN + then: -right <= -MIN + + Given: -right <= -MIN + then: MIN + -right <= MIN + -MIN + then: MIN + -right <= 0 + then: MIN - right <= 0 + then: MIN - right <= MAX + THEN: MIN - right CANNOT overflow MAX + + Given: right < 0 + then: 0 - right > 0 - 0 + then: 0 - right > 0 + then: -right > 0 + + Given: -right > 0 + then: MIN + (-right) > MIN + 0 + then: MIN - right > MIN + 0 + then: MIN - right > MIN + THEN: MIN - right CANNOT overflow MIN + + Define: legroom = MIN - right + + Given: legroom = MIN - right + then: legroom + right = MIN - right + right + then: legroom + right = MIN + */ + const int64_t legroom = INT64_MIN - right; + + if (left < legroom) { + /** + Given: left < legroom + then: left + right < legroom + right + + Given: legroom + right = MIN + and: left + right < legroom + right + then: left + right < MIN + THEN: left + right WILL overflow MIN! + */ + return true; + } else { + /** + Given: left >= legroom + then: left + right >= legroom + right + + Given: legroom + right = MIN + and: left + right >= legroom + right + THEN: left + right >= MIN + + Given: left + right <= MAX + and: left + right >= MIN + THEN: left + right is in [MIN, MAX] + */ + return false; + } + } else if (right > 0) { + /** + Given: right > 0 + then: left + right > left + 0 + then: left + right > left + then: left + right >= left [Weakening] + + Given: left >= MIN + and: left + right >= left + then: left + right >= MIN + THEN: left + right cannot overflow MIN + */ + + /** + Given: right <= MAX + then: 0 - right >= 0 - MAX + then: -right >= -MAX + + Given: -right >= -MAX + then: MAX + -right >= MAX + -MAX + then: MAX + -right >= 0 + then: MAX - right >= 0 + then: MAX - right >= MIN + THEN: MAX - right CANNOT overflow MIN + + Given: right > 0 + then: 0 - right < 0 - 0 + then: -right < 0 + then: MAX + (-right) < MAX + 0 + then: MAX + (-right) < MAX + then: MAX - right < MAX + THEN: MAX - right CANNOT overflow MAX + + Define: headroom = MAX - right + + Given: headroom = MAX - right; + then: headroom + right = MAX - right + right + then: headroom + right = MAX + */ + int64_t headroom = INT64_MAX - right; + + if (left > headroom) { + /** + Given: left > headroom + then: left + right > headroom + right + + Given: left + right > headroom + right + and: headroom + right = MAX + then: left + right > MAX + THEN: left + right WILL overflow MAX! + */ + return true; + } else { + /** + Given: left <= headroom + then: left + rigth <= headroom + right + + Given: left + right <= headroom + right + and: headroom + right = MAX + then: left + right <= MAX + THEN: left + right CANNOT overflow MAX + */ + return false; + } + } else { + /** + Given: right = 0 + and: left + right = left + 0 + then: left + right = left + + Given: left <= MAX + and: left >= MIN + and: left + right = left + then: left + right <= MAX + and: left + right >= MIN + THEN: left + right is in [MIN, MAX] + */ + return false; + } +} + +/// Return 'true' iff (left - right) would overflow with int64 +static BSON_INLINE bool +_mcd_i64_sub_would_overflow (int64_t left, int64_t right) +{ + // Lemma: N - M = N + (-M), therefore (N - M) is bounded iff (N + -M) + // is bounded. + if (right > 0) { + return _mcd_i64_add_would_overflow (left, -right); + } else if (right < 0) { + if (left > 0) { + return _mcd_i64_add_would_overflow (-left, right); + } else { + // Both negative. Subtracting two negatives will never overflow + return false; + } + } else { + // Given: right = 0 + // then: left - right = left - 0 + // then: left - right = left + //? THEN: left - right is bounded + return false; + } +} + +#endif // MCD_INTEGER_H_INCLUDED diff --git a/src/mongoc/mcd-rpc.c b/src/mongoc/mcd-rpc.c new file mode 100644 index 00000000..446e4ef8 --- /dev/null +++ b/src/mongoc/mcd-rpc.c @@ -0,0 +1,2730 @@ +#include "mcd-rpc.h" + +// Header-only dependency. Does NOT require linking with libmongoc. +#define MONGOC_INSIDE +#include "mongoc-iovec.h" +#undef MONGOC_INSIDE + +#include + + +typedef struct _mcd_rpc_message_header mcd_rpc_message_header; + +typedef struct _mcd_rpc_op_compressed mcd_rpc_op_compressed; + +typedef struct _mcd_rpc_op_msg_section mcd_rpc_op_msg_section; +typedef struct _mcd_rpc_op_msg mcd_rpc_op_msg; + +typedef struct _mcd_rpc_op_reply mcd_rpc_op_reply; +typedef struct _mcd_rpc_op_update mcd_rpc_op_update; +typedef struct _mcd_rpc_op_insert mcd_rpc_op_insert; +typedef struct _mcd_rpc_op_query mcd_rpc_op_query; +typedef struct _mcd_rpc_op_get_more mcd_rpc_op_get_more; +typedef struct _mcd_rpc_op_delete mcd_rpc_op_delete; +typedef struct _mcd_rpc_op_kill_cursors mcd_rpc_op_kill_cursors; + + +// See: https://www.mongodb.com/docs/manual/reference/mongodb-wire-protocol +struct _mcd_rpc_message_header { + int32_t message_length; + int32_t request_id; + int32_t response_to; + int32_t op_code; + bool is_in_iovecs_state; // Not part of actual message. +}; + +struct _mcd_rpc_op_compressed { + mcd_rpc_message_header header; + int32_t original_opcode; + int32_t uncompressed_size; + uint8_t compressor_id; + const void *compressed_message; // Non-owning. + size_t compressed_message_len; // Not part of actual message. +}; + +struct _mcd_rpc_op_msg_section { + uint8_t kind; + + union payload { + // Kind 0. + struct body { + int32_t section_len; // Not part of actual message. + const void *bson; // bson_t data, non-owning. + } body; + + // Kind 1. + struct document_sequence { + int32_t section_len; + const char *identifier; // Non-owning. + size_t identifier_len; // Not part of actual message. + const void *bson_objects; // Array of bson_t data, non-owning. + size_t bson_objects_len; // Not part of actual message. + } document_sequence; + } payload; +}; + +struct _mcd_rpc_op_msg { + mcd_rpc_message_header header; + uint32_t flag_bits; + mcd_rpc_op_msg_section *sections; // Owning. + size_t sections_count; // Not part of actual message. + uint32_t checksum; // Optional, ignored by Drivers. + bool checksum_set; // Not part of actual message. +}; + +struct _mcd_rpc_op_reply { + mcd_rpc_message_header header; + int32_t response_flags; + int64_t cursor_id; + int32_t starting_from; + int32_t number_returned; + const void *documents; // Array of bson_t data, non-owning. + size_t documents_len; // Not part of actual message. +}; + +struct _mcd_rpc_op_update { + mcd_rpc_message_header header; + const char *full_collection_name; // Non-owning. + size_t full_collection_name_len; // Not part of actual message. + int32_t flags; + const void *selector; // bson_t data, non-owning. + const void *update; // bson_t data, non-owning. +}; + +struct _mcd_rpc_op_insert { + mcd_rpc_message_header header; + int32_t flags; + const char *full_collection_name; // Non-owning. + size_t full_collection_name_len; // Not part of actual message. + const void *documents; // Array of bson_t data, non-owning. + size_t documents_len; // Not part of actual message. +}; + +struct _mcd_rpc_op_query { + mcd_rpc_message_header header; + int32_t flags; + const char *full_collection_name; // Non-owning. + size_t full_collection_name_len; // Not part of actual message. + int32_t number_to_skip; + int32_t number_to_return; + const void *query; // bson_t, non-owning. + const void *return_fields_selector; // Optional bson_t, non-owning. +}; + +struct _mcd_rpc_op_get_more { + mcd_rpc_message_header header; + const char *full_collection_name; // Non-owning. + size_t full_collection_name_len; // Not part of actual message. + int32_t number_to_return; + int64_t cursor_id; +}; + +struct _mcd_rpc_op_delete { + mcd_rpc_message_header header; + const char *full_collection_name; + size_t full_collection_name_len; // Not part of actual message. + int32_t flags; + const void *selector; // bson_t data, non-owning. +}; + +struct _mcd_rpc_op_kill_cursors { + mcd_rpc_message_header header; + int32_t zero; // Reserved. + int32_t number_of_cursor_ids; + int64_t *cursor_ids; // Array of int64_t, owning. +}; + +union _mcd_rpc_message { + mcd_rpc_message_header msg_header; // Common initial sequence. + + mcd_rpc_op_compressed op_compressed; + mcd_rpc_op_msg op_msg; + + mcd_rpc_op_reply op_reply; + mcd_rpc_op_update op_update; + mcd_rpc_op_insert op_insert; + mcd_rpc_op_query op_query; + mcd_rpc_op_get_more op_get_more; + mcd_rpc_op_delete op_delete; + mcd_rpc_op_kill_cursors op_kill_cursors; +}; + + +// The minimum byte length of a valid RPC message is 16 bytes (messageHeader is +// the common initial sequence for all opcodes). RPC message lengths less than +// 16 may be encountered parsing due to invalid or malformed input. +#define MONGOC_RPC_MINIMUM_MESSAGE_LENGTH INT32_C (16) + +// The minimum byte length of a valid BSON document is 5 bytes (empty document): +// - length (int32): total document length (including itself). +// - "\x00": document terminator. +// BSON document lengths less than 5 may be encountered during parsing due to +// invalid or malformed input. +#define MONGOC_RPC_MINIMUM_BSON_LENGTH INT32_C (5) + +// To avoid unexpected behavior on big endian targets after +// `mcd_rpc_message_to_iovecs` due to fields being converted to little endian, +// forbid use of accessors unless the RPC message has been reset to an +// initialized state by asserting `!is_in_iovecs_state` even on little endian +// targets. +#define ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS \ + if (1) { \ + BSON_ASSERT_PARAM (rpc); \ + BSON_ASSERT (!rpc->msg_header.is_in_iovecs_state); \ + } else \ + (void) 0 + + +static int32_t +_int32_from_le (const void *data) +{ + BSON_ASSERT_PARAM (data); + return bson_iter_int32_unsafe (&(bson_iter_t){.raw = data}); +} + + +// In addition to validating expected size against remaining bytes, ensure +// proper conversion from little endian format. +#define MONGOC_RPC_CONSUME(type, raw_type, from_le) \ + static bool _consume_##type ( \ + type *target, const uint8_t **ptr, size_t *remaining_bytes) \ + { \ + BSON_ASSERT_PARAM (target); \ + BSON_ASSERT_PARAM (ptr); \ + BSON_ASSERT_PARAM (remaining_bytes); \ + \ + if (*remaining_bytes < sizeof (type)) { \ + return false; \ + } \ + \ + raw_type raw; \ + memcpy (&raw, *ptr, sizeof (type)); \ + \ + const raw_type native = from_le (raw); \ + memcpy (target, &native, sizeof (type)); \ + \ + *ptr += sizeof (type); \ + *remaining_bytes -= sizeof (type); \ + \ + return true; \ + } + +MONGOC_RPC_CONSUME (uint8_t, uint8_t, (uint8_t)) +MONGOC_RPC_CONSUME (int32_t, uint32_t, BSON_UINT32_FROM_LE) +MONGOC_RPC_CONSUME (uint32_t, uint32_t, BSON_UINT32_FROM_LE) +MONGOC_RPC_CONSUME (int64_t, uint64_t, BSON_UINT64_FROM_LE) + +static bool +_consume_utf8 (const char **target, + size_t *length, + const uint8_t **ptr, + size_t *remaining_bytes) +{ + BSON_ASSERT_PARAM (target); + BSON_ASSERT_PARAM (length); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + + *target = (const char *) *ptr; + + const uint8_t *iter = *ptr; + size_t rem = *remaining_bytes; + + while (rem > 0u && *iter != '\0') { + iter += 1u; + rem -= 1u; + } + + if (rem == 0u) { + return false; + } + + // Consume string including the null terminator. + iter += 1u; + rem -= 1u; + *length = *remaining_bytes - rem; + *ptr = iter; + *remaining_bytes = rem; + + return true; +} + + +static bool +_consume_reserved_zero (const uint8_t **ptr, size_t *remaining_bytes) +{ + int32_t zero; + + if (!_consume_int32_t (&zero, ptr, remaining_bytes)) { + return false; + } + + if (zero != 0) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // ZERO as invalid input. + return false; + } + + return true; +} + + +static bool +_consume_bson_objects (const uint8_t **ptr, + size_t *remaining_bytes, + int32_t *num_parsed, + int32_t limit) +{ + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + BSON_ASSERT (num_parsed || true); + + int32_t count = 0; + + // Validate document count and lengths. + while ((count < limit) && (*remaining_bytes > 0u)) { + int32_t doc_len; + if (!_consume_int32_t (&doc_len, ptr, remaining_bytes)) { + return false; + } + + if (doc_len < MONGOC_RPC_MINIMUM_BSON_LENGTH || + bson_cmp_greater_su (doc_len, *remaining_bytes + sizeof (int32_t))) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // document as invalid input. + return false; + } + + // Consume rest of document without validation. + *ptr += (size_t) doc_len - sizeof (int32_t); + *remaining_bytes -= (size_t) doc_len - sizeof (int32_t); + + count += 1; + } + + if (num_parsed) { + *num_parsed = count; + } + + return true; +} + + +static bool +_consume_op_compressed (mcd_rpc_message *rpc, + const uint8_t **ptr, + size_t *remaining_bytes) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + + mcd_rpc_op_compressed *const op_compressed = &rpc->op_compressed; + + if (!_consume_int32_t ( + &op_compressed->original_opcode, ptr, remaining_bytes)) { + return false; + } + + if (!_consume_int32_t ( + &op_compressed->uncompressed_size, ptr, remaining_bytes)) { + return false; + } + + if (!_consume_uint8_t ( + &op_compressed->compressor_id, ptr, remaining_bytes)) { + return false; + } + + // Consume compressedMessage without validation. + op_compressed->compressed_message = *ptr; + op_compressed->compressed_message_len = *remaining_bytes; + *ptr += *remaining_bytes; + *remaining_bytes = 0u; + + return true; +} + + +static bool +_consume_op_msg_section (mcd_rpc_op_msg *op_msg, + const uint8_t **ptr, + size_t *remaining_bytes, + size_t *capacity, + bool *found_kind_0) +{ + BSON_ASSERT_PARAM (op_msg); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (found_kind_0); + + mcd_rpc_op_msg_section section; + + if (!_consume_uint8_t (§ion.kind, ptr, remaining_bytes)) { + return false; + } + + // There is no ordering implied by payload types. A section with payload type + // 1 can be serialized before payload type 0. + if (section.kind == 0) { + if (*found_kind_0) { + *ptr -= sizeof (uint8_t); // Revert so *data_end points to start of + // section as invalid input. + return false; + } + + *found_kind_0 = true; + } + + switch (section.kind) { + case 0: { // Body + section.payload.body.section_len = _int32_from_le (*ptr); + section.payload.body.bson = *ptr; + + int32_t num_parsed = 0; + if (!_consume_bson_objects (ptr, remaining_bytes, &num_parsed, 1) || + num_parsed != 1) { + return false; + } + + break; + } + + case 1: { // Document Sequence + if (!_consume_int32_t (§ion.payload.document_sequence.section_len, + ptr, + remaining_bytes)) { + return false; + } + + // Minimum byte length of a valid document sequence section is 4 bytes + // (section length). Actual minimum length would also account for the + // identifier field, but 4 bytes is sufficient to avoid unsigned integer + // overflow when computing `remaining_section_bytes` and to encourage as + // much progress is made parsing input data as able. + if (bson_cmp_less_su (section.payload.document_sequence.section_len, + sizeof (int32_t))) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // document sequence as invalid input. + return false; + } + + size_t remaining_section_bytes = + (size_t) section.payload.document_sequence.section_len - + sizeof (int32_t); + + // Section length exceeds remaining data. + if (remaining_section_bytes > *remaining_bytes) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // document sequence as invalid input. + return false; + } + + // Consume identifier without validating uniqueness. + { + const uint8_t *const identifier_begin = *ptr; + if (!_consume_utf8 (§ion.payload.document_sequence.identifier, + §ion.payload.document_sequence.identifier_len, + ptr, + &remaining_section_bytes)) { + return false; + } + *remaining_bytes -= (size_t) (*ptr - identifier_begin); + } + + section.payload.document_sequence.bson_objects = *ptr; + section.payload.document_sequence.bson_objects_len = + remaining_section_bytes; + + _consume_bson_objects (ptr, &remaining_section_bytes, NULL, INT32_MAX); + + // Should have exhausted all bytes in the section. + if (remaining_section_bytes != 0u) { + return false; + } + + *remaining_bytes -= + (size_t) (*ptr - (const uint8_t *) + section.payload.document_sequence.bson_objects); + + break; + } + + default: + *ptr -= sizeof (uint8_t); // Revert so *data_end points to start of kind + // as invalid input. + return false; + } + + // Expand sections capacity if required. + if (op_msg->sections_count >= *capacity) { + *capacity *= 2u; + op_msg->sections = bson_realloc ( + op_msg->sections, *capacity * sizeof (mcd_rpc_op_msg_section)); + } + + // Append the valid section. + op_msg->sections[op_msg->sections_count++] = section; + + return true; +} + +static bool +_consume_op_msg (mcd_rpc_message *rpc, + const uint8_t **ptr, + size_t *remaining_bytes) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + + mcd_rpc_op_msg *const op_msg = &rpc->op_msg; + + if (!_consume_uint32_t (&op_msg->flag_bits, ptr, remaining_bytes)) { + return false; + } + + { + const uint32_t defined_bits = MONGOC_OP_MSG_FLAG_CHECKSUM_PRESENT | + MONGOC_OP_MSG_FLAG_MORE_TO_COME | + MONGOC_OP_MSG_FLAG_EXHAUST_ALLOWED; + + // Clients MUST error if any unsupported or undefined required bits are + // set to 1 and MUST ignore all undefined optional bits. + if (((op_msg->flag_bits & UINT32_C (0x0000FFFF)) & ~defined_bits) != 0u) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // flagBits as invalid input. + return false; + } + } + + // Each message contains one or more sections. Preallocate space for two + // sections, which should cover the most frequent cases. + size_t capacity = 2u; + op_msg->sections = bson_malloc (capacity * sizeof (mcd_rpc_op_msg_section)); + op_msg->sections_count = 0u; + + // A fully constructed OP_MSG MUST contain exactly one Payload Type 0, and + // optionally any number of Payload Type 1 where each identifier MUST be + // unique per message. + { + bool found_kind_0 = false; + + // A section requires at least 5 bytes for kind (1) + length (4). + while (*remaining_bytes > 4u) { + if (!_consume_op_msg_section ( + op_msg, ptr, remaining_bytes, &capacity, &found_kind_0)) { + return false; + } + } + + if (!found_kind_0) { + return false; + } + } + + if ((op_msg->flag_bits & MONGOC_OP_MSG_FLAG_CHECKSUM_PRESENT) != 0u) { + if (!_consume_uint32_t (&op_msg->checksum, ptr, remaining_bytes)) { + return false; + } + + op_msg->checksum_set = true; + } + + return true; +} + + +static bool +_consume_op_reply (mcd_rpc_message *rpc, + const uint8_t **ptr, + size_t *remaining_bytes) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + + mcd_rpc_op_reply *const op_reply = &rpc->op_reply; + + if (!_consume_int32_t (&op_reply->response_flags, ptr, remaining_bytes)) { + return false; + } + + if (!_consume_int64_t (&op_reply->cursor_id, ptr, remaining_bytes)) { + return false; + } + + if (!_consume_int32_t (&op_reply->starting_from, ptr, remaining_bytes)) { + return false; + } + + if (!_consume_int32_t (&op_reply->number_returned, ptr, remaining_bytes)) { + return false; + } + + if (op_reply->number_returned < 0) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // numberReturned as invalid input. + return false; + } + + if (op_reply->number_returned > 0) { + op_reply->documents = *ptr; + op_reply->documents_len = *remaining_bytes; + } else { + op_reply->documents = NULL; + op_reply->documents_len = 0u; + } + + int32_t num_parsed = 0; + if (!_consume_bson_objects ( + ptr, remaining_bytes, &num_parsed, op_reply->number_returned) || + num_parsed != op_reply->number_returned) { + return false; + } + + return true; +} + + +static bool +_consume_op_update (mcd_rpc_message *rpc, + const uint8_t **ptr, + size_t *remaining_bytes) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + + mcd_rpc_op_update *const op_update = &rpc->op_update; + + if (!_consume_reserved_zero (ptr, remaining_bytes)) { + return false; + } + + if (!_consume_utf8 (&op_update->full_collection_name, + &op_update->full_collection_name_len, + ptr, + remaining_bytes)) { + return false; + } + + if (!_consume_int32_t (&op_update->flags, ptr, remaining_bytes)) { + return false; + } + + // Bits 2-31 are reserved. Must be set to 0. + if ((op_update->flags & ~(0x00000003)) != 0) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // flags as invalid input. + return false; + } + + int32_t num_parsed = 0; + + op_update->selector = *ptr; + if (!_consume_bson_objects (ptr, remaining_bytes, &num_parsed, 1) || + num_parsed != 1) { + return false; + } + + op_update->update = *ptr; + if (!_consume_bson_objects (ptr, remaining_bytes, &num_parsed, 1) || + num_parsed != 1) { + return false; + } + + return true; +} + + +static bool +_consume_op_insert (mcd_rpc_message *rpc, + const uint8_t **ptr, + size_t *remaining_bytes) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + + mcd_rpc_op_insert *const op_insert = &rpc->op_insert; + + if (!_consume_int32_t (&op_insert->flags, ptr, remaining_bytes)) { + return false; + } + + // Bits 1-31 are reserved. Must be set to 0. + if ((op_insert->flags & ~(0x00000001)) != 0) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // flags as invalid input. + return false; + } + + if (!_consume_utf8 (&op_insert->full_collection_name, + &op_insert->full_collection_name_len, + ptr, + remaining_bytes)) { + return false; + } + + op_insert->documents = *ptr; + op_insert->documents_len = *remaining_bytes; + + int32_t num_parsed = 0; + if (!_consume_bson_objects (ptr, remaining_bytes, &num_parsed, INT32_MAX) || + num_parsed == 0) { + return false; + } + + return true; +} + + +static bool +_consume_op_query (mcd_rpc_message *rpc, + const uint8_t **ptr, + size_t *remaining_bytes) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + + mcd_rpc_op_query *const op_query = &rpc->op_query; + + if (!_consume_int32_t (&op_query->flags, ptr, remaining_bytes)) { + return false; + } + + // Bit 0 is reserved. Must be set to 0. + if ((op_query->flags & 0x01) != 0) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // flags as invalid input. + return false; + } + + // Bits 8-31 are reserved. Must be set to 0. + if ((op_query->flags & ~(0x0000007F)) != 0) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // flags as invalid input. + return false; + } + + if (!_consume_utf8 (&op_query->full_collection_name, + &op_query->full_collection_name_len, + ptr, + remaining_bytes)) { + return false; + } + + if (!_consume_int32_t (&op_query->number_to_skip, ptr, remaining_bytes)) { + return false; + } + + if (!_consume_int32_t (&op_query->number_to_return, ptr, remaining_bytes)) { + return false; + } + + int32_t num_parsed = 0; + + op_query->query = *ptr; + if (!_consume_bson_objects (ptr, remaining_bytes, &num_parsed, 1) || + num_parsed != 1) { + return false; + } + + op_query->return_fields_selector = *ptr; + if (!_consume_bson_objects (ptr, remaining_bytes, &num_parsed, 1)) { + return false; + } + + // returnFieldsSelector is optional. + if (num_parsed == 0) { + op_query->return_fields_selector = NULL; + } + + return true; +} + + +static bool +_consume_op_get_more (mcd_rpc_message *rpc, + const uint8_t **ptr, + size_t *remaining_bytes) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + + mcd_rpc_op_get_more *const op_get_more = &rpc->op_get_more; + + if (!_consume_reserved_zero (ptr, remaining_bytes)) { + return false; + } + + if (!_consume_utf8 (&op_get_more->full_collection_name, + &op_get_more->full_collection_name_len, + ptr, + remaining_bytes)) { + return false; + } + + if (!_consume_int32_t ( + &op_get_more->number_to_return, ptr, remaining_bytes)) { + return false; + } + + if (!_consume_int64_t (&op_get_more->cursor_id, ptr, remaining_bytes)) { + return false; + } + + return true; +} + + +static bool +_consume_op_delete (mcd_rpc_message *rpc, + const uint8_t **ptr, + size_t *remaining_bytes) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + + mcd_rpc_op_delete *const op_delete = &rpc->op_delete; + + if (!_consume_reserved_zero (ptr, remaining_bytes)) { + return false; + } + + if (!_consume_utf8 (&op_delete->full_collection_name, + &op_delete->full_collection_name_len, + ptr, + remaining_bytes)) { + return false; + } + + if (!_consume_int32_t (&op_delete->flags, ptr, remaining_bytes)) { + return false; + } + + // Bits 1-31 are reserved. Must be set to 0. + if ((op_delete->flags & ~(0x00000001)) != 0) { + *ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // flags as invalid input. + return false; + } + + op_delete->selector = *ptr; + + int32_t num_parsed = 0; + if (!_consume_bson_objects (ptr, remaining_bytes, &num_parsed, 1) || + num_parsed != 1) { + return false; + } + + return true; +} + + +static bool +_consume_op_kill_cursors (mcd_rpc_message *rpc, + const uint8_t **ptr, + size_t *remaining_bytes) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (ptr); + BSON_ASSERT_PARAM (remaining_bytes); + + mcd_rpc_op_kill_cursors *op_kill_cursors = &rpc->op_kill_cursors; + + if (!_consume_reserved_zero (ptr, remaining_bytes)) { + return false; + } + + if (!_consume_int32_t ( + &op_kill_cursors->number_of_cursor_ids, ptr, remaining_bytes)) { + return false; + } + + if (op_kill_cursors->number_of_cursor_ids < 0 || + // Truncation may (deliberately) leave unparsed bytes that will later + // trigger validation failure due to unexpected remaining bytes. + bson_cmp_greater_su (op_kill_cursors->number_of_cursor_ids, + *remaining_bytes / sizeof (int64_t))) { + *ptr -= sizeof (int32_t); // Revert so *data_len points to start of + // numberOfCursorIds as invalid input. + return false; + } + + const size_t cursor_ids_length = + (size_t) op_kill_cursors->number_of_cursor_ids * sizeof (int64_t); + + bson_free (op_kill_cursors->cursor_ids); + + if (op_kill_cursors->number_of_cursor_ids > 0) { + op_kill_cursors->cursor_ids = bson_malloc (cursor_ids_length); + for (int32_t i = 0; i < op_kill_cursors->number_of_cursor_ids; ++i) { + if (!_consume_int64_t ( + op_kill_cursors->cursor_ids + i, ptr, remaining_bytes)) { + return false; + } + } + } else { + op_kill_cursors->cursor_ids = NULL; + } + + return true; +} + + +mcd_rpc_message * +mcd_rpc_message_from_data (const void *data, + size_t length, + const void **data_end) +{ + BSON_ASSERT_PARAM (data); + BSON_ASSERT (data_end || true); + + mcd_rpc_message *rpc = bson_malloc (sizeof (mcd_rpc_message)); + mcd_rpc_message *ret = NULL; + + *rpc = (mcd_rpc_message){.msg_header = {0}}; + + if (!mcd_rpc_message_from_data_in_place (rpc, data, length, data_end)) { + goto fail; + } + + ret = rpc; + rpc = NULL; + +fail: + mcd_rpc_message_destroy (rpc); + return ret; +} + +bool +mcd_rpc_message_from_data_in_place (mcd_rpc_message *rpc, + const void *data, + size_t length, + const void **data_end) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT_PARAM (data); + BSON_ASSERT (data_end || true); + + bool ret = false; + + size_t remaining_bytes = length; + + const uint8_t *ptr = data; + + if (!_consume_int32_t ( + &rpc->msg_header.message_length, &ptr, &remaining_bytes)) { + goto fail; + } + + if (rpc->msg_header.message_length < MONGOC_RPC_MINIMUM_MESSAGE_LENGTH || + bson_cmp_greater_su (rpc->msg_header.message_length, + remaining_bytes + sizeof (int32_t))) { + ptr -= sizeof (int32_t); // Revert so *data_end points to start of + // messageLength as invalid input. + goto fail; + } + + // Use reported message length as upper bound. + remaining_bytes = (size_t) rpc->msg_header.message_length - sizeof (int32_t); + + if (!_consume_int32_t ( + &rpc->msg_header.request_id, &ptr, &remaining_bytes)) { + goto fail; + } + + if (!_consume_int32_t ( + &rpc->msg_header.response_to, &ptr, &remaining_bytes)) { + goto fail; + } + + if (!_consume_int32_t (&rpc->msg_header.op_code, &ptr, &remaining_bytes)) { + goto fail; + } + + switch (rpc->msg_header.op_code) { + case MONGOC_OP_CODE_COMPRESSED: + if (!_consume_op_compressed (rpc, &ptr, &remaining_bytes)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_MSG: + if (!_consume_op_msg (rpc, &ptr, &remaining_bytes)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_REPLY: + if (!_consume_op_reply (rpc, &ptr, &remaining_bytes)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_UPDATE: + if (!_consume_op_update (rpc, &ptr, &remaining_bytes)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_INSERT: + if (!_consume_op_insert (rpc, &ptr, &remaining_bytes)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_QUERY: + if (!_consume_op_query (rpc, &ptr, &remaining_bytes)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_GET_MORE: + if (!_consume_op_get_more (rpc, &ptr, &remaining_bytes)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_DELETE: + if (!_consume_op_delete (rpc, &ptr, &remaining_bytes)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_KILL_CURSORS: + if (!_consume_op_kill_cursors (rpc, &ptr, &remaining_bytes)) { + goto fail; + } + break; + + default: + ptr -= sizeof (int32_t); // Revert so *data_end points to start of opCode + // as invalid input. + goto fail; + } + + // Number of bytes parsed do not match the reported message length. + if (remaining_bytes > 0) { + goto fail; + } + + ret = true; + +fail: + if (data_end) { + *data_end = ptr; + } + + return ret; +} + +static void +_append_iovec_reserve_space_for (mongoc_iovec_t **iovecs, + size_t *capacity, + const mongoc_iovec_t *header_iovecs, + size_t additional_capacity) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (header_iovecs); + + // Expect this function to be invoked only once after initializing the + // `header_iovecs` array. + BSON_ASSERT (*capacity == 4u); + + *capacity += additional_capacity; + *iovecs = bson_malloc (*capacity * sizeof (mongoc_iovec_t)); + memcpy (*iovecs, header_iovecs, 4u * sizeof (mongoc_iovec_t)); +} + +static bool +_append_iovec (mongoc_iovec_t *iovecs, + size_t *capacity, + size_t *count, + mongoc_iovec_t iovec) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (count); + + if (!iovec.iov_base || iovec.iov_len == 0u) { + return false; + } + + // Expect iovecs array capacity to have been reserved upfront according to + // the upper bound of potential iovec objects required for the opcode being + // converted. This is to minimize (re)allocations. + BSON_ASSERT (*count < *capacity); + + iovecs[*count] = iovec; + *count += 1u; + + return true; +} + +#define MONGOC_RPC_APPEND_IOVEC(type, raw_type, to_le) \ + static bool _append_iovec_##type ( \ + mongoc_iovec_t *iovecs, size_t *capacity, size_t *count, type *value) \ + { \ + raw_type storage; \ + memcpy (&storage, value, sizeof (raw_type)); \ + storage = to_le (storage); \ + memcpy (value, &storage, sizeof (raw_type)); \ + return _append_iovec (iovecs, \ + capacity, \ + count, \ + (mongoc_iovec_t){ \ + .iov_base = (void *) value, \ + .iov_len = sizeof (type), \ + }); \ + } + +MONGOC_RPC_APPEND_IOVEC (uint8_t, uint8_t, (uint8_t)) +MONGOC_RPC_APPEND_IOVEC (int32_t, uint32_t, BSON_UINT32_TO_LE) +MONGOC_RPC_APPEND_IOVEC (uint32_t, uint32_t, BSON_UINT32_TO_LE) +MONGOC_RPC_APPEND_IOVEC (int64_t, uint64_t, BSON_UINT64_TO_LE) + +static bool +_append_iovec_data (mongoc_iovec_t *iovecs, + size_t *capacity, + size_t *count, + const void *data, + size_t length) +{ + return _append_iovec (iovecs, + capacity, + count, + (mongoc_iovec_t){ + .iov_base = (void *) data, + .iov_len = length, + }); +} + +static bool +_append_iovec_reserved_zero (mongoc_iovec_t *iovecs, + size_t *capacity, + size_t *count) +{ + static int32_t zero = 0u; + + return _append_iovec (iovecs, + capacity, + count, + (mongoc_iovec_t){ + .iov_base = (void *) &zero, + .iov_len = sizeof (zero), + }); +} + +static bool +_append_iovec_op_compressed (mongoc_iovec_t **iovecs, + size_t *capacity, + size_t *count, + mcd_rpc_op_compressed *op_compressed, + const mongoc_iovec_t *header_iovecs) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (count); + BSON_ASSERT_PARAM (op_compressed); + BSON_ASSERT_PARAM (header_iovecs); + + _append_iovec_reserve_space_for (iovecs, capacity, header_iovecs, 4u); + + if (!_append_iovec_int32_t ( + *iovecs, capacity, count, &op_compressed->original_opcode)) { + return false; + } + + if (!_append_iovec_int32_t ( + *iovecs, capacity, count, &op_compressed->uncompressed_size)) { + return false; + } + + if (!_append_iovec_uint8_t ( + *iovecs, capacity, count, &op_compressed->compressor_id)) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_compressed->compressed_message, + op_compressed->compressed_message_len)) { + return false; + } + + return true; +} + +static bool +_count_section_iovecs (const mcd_rpc_op_msg *op_msg, size_t *section_iovecs) +{ + BSON_ASSERT_PARAM (op_msg); + BSON_ASSERT_PARAM (section_iovecs); + + for (size_t i = 0u; i < op_msg->sections_count; ++i) { + *section_iovecs += 1u; + + switch (op_msg->sections[i].kind) { + case 0: // Body. + *section_iovecs += 1u; + break; + + case 1: // Document Sequence. + *section_iovecs += 3u; + break; + + default: + return false; + } + } + + return true; +} + +static bool +_append_iovec_op_msg (mongoc_iovec_t **iovecs, + size_t *capacity, + size_t *count, + mcd_rpc_op_msg *op_msg, + const mongoc_iovec_t *header_iovecs) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (count); + BSON_ASSERT_PARAM (op_msg); + BSON_ASSERT_PARAM (header_iovecs); + + size_t section_iovecs = 0u; + if (!_count_section_iovecs (op_msg, §ion_iovecs)) { + return false; + } + + _append_iovec_reserve_space_for ( + iovecs, capacity, header_iovecs, 2u + section_iovecs); + + if (!_append_iovec_uint32_t (*iovecs, capacity, count, &op_msg->flag_bits)) { + return false; + } + + for (size_t i = 0u; i < op_msg->sections_count; ++i) { + mcd_rpc_op_msg_section *section = &op_msg->sections[i]; + + if (!section) { + return false; + } + + if (!_append_iovec_uint8_t (*iovecs, capacity, count, §ion->kind)) { + return false; + } + + switch (section->kind) { + case 0: // Body + if (!_append_iovec_data (*iovecs, + capacity, + count, + section->payload.body.bson, + (size_t) section->payload.body.section_len)) { + return false; + } + break; + + case 1: // Document Sequence + if (!_append_iovec_int32_t ( + *iovecs, + capacity, + count, + §ion->payload.document_sequence.section_len)) { + return false; + } + + if (!_append_iovec_data ( + *iovecs, + capacity, + count, + section->payload.document_sequence.identifier, + section->payload.document_sequence.identifier_len)) { + return false; + } + + if (!_append_iovec_data ( + *iovecs, + capacity, + count, + section->payload.document_sequence.bson_objects, + section->payload.document_sequence.bson_objects_len)) { + return false; + } + + break; + + default: + return false; + } + } + + if (op_msg->checksum_set) { + if (!_append_iovec_uint32_t ( + *iovecs, capacity, count, &op_msg->checksum)) { + return false; + } + } + + return true; +} + +static bool +_append_iovec_op_reply (mongoc_iovec_t **iovecs, + size_t *capacity, + size_t *count, + mcd_rpc_op_reply *op_reply, + const mongoc_iovec_t *header_iovecs) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (count); + BSON_ASSERT_PARAM (op_reply); + BSON_ASSERT_PARAM (header_iovecs); + + _append_iovec_reserve_space_for (iovecs, capacity, header_iovecs, 5u); + + if (!_append_iovec_int32_t ( + *iovecs, capacity, count, &op_reply->response_flags)) { + return false; + } + + if (!_append_iovec_int64_t ( + *iovecs, capacity, count, &op_reply->cursor_id)) { + return false; + } + + if (!_append_iovec_int32_t ( + *iovecs, capacity, count, &op_reply->starting_from)) { + return false; + } + + if (!_append_iovec_int32_t ( + *iovecs, capacity, count, &op_reply->number_returned)) { + return false; + } + + if (op_reply->number_returned > 0 && + !_append_iovec_data (*iovecs, + capacity, + count, + op_reply->documents, + op_reply->documents_len)) { + return false; + } + + return true; +} + +static bool +_append_iovec_op_update (mongoc_iovec_t **iovecs, + size_t *capacity, + size_t *count, + mcd_rpc_op_update *op_update, + const mongoc_iovec_t *header_iovecs) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (count); + BSON_ASSERT_PARAM (op_update); + BSON_ASSERT_PARAM (header_iovecs); + + _append_iovec_reserve_space_for (iovecs, capacity, header_iovecs, 5u); + + if (!_append_iovec_reserved_zero (*iovecs, capacity, count)) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_update->full_collection_name, + op_update->full_collection_name_len)) { + return false; + } + + if (!_append_iovec_int32_t (*iovecs, capacity, count, &op_update->flags)) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_update->selector, + (size_t) _int32_from_le (op_update->selector))) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_update->update, + (size_t) _int32_from_le (op_update->update))) { + return false; + } + + return true; +} + +static bool +_append_iovec_op_insert (mongoc_iovec_t **iovecs, + size_t *capacity, + size_t *count, + mcd_rpc_op_insert *op_insert, + const mongoc_iovec_t *header_iovecs) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (count); + BSON_ASSERT_PARAM (op_insert); + BSON_ASSERT_PARAM (header_iovecs); + + _append_iovec_reserve_space_for (iovecs, capacity, header_iovecs, 3u); + + if (!_append_iovec_int32_t (*iovecs, capacity, count, &op_insert->flags)) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_insert->full_collection_name, + op_insert->full_collection_name_len)) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_insert->documents, + op_insert->documents_len)) { + return false; + } + + + return true; +} + +static bool +_append_iovec_op_query (mongoc_iovec_t **iovecs, + size_t *capacity, + size_t *count, + mcd_rpc_op_query *op_query, + const mongoc_iovec_t *header_iovecs) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (count); + BSON_ASSERT_PARAM (op_query); + BSON_ASSERT_PARAM (header_iovecs); + + _append_iovec_reserve_space_for ( + iovecs, + capacity, + header_iovecs, + 5u + (size_t) (!!op_query->return_fields_selector)); + + if (!_append_iovec_int32_t (*iovecs, capacity, count, &op_query->flags)) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_query->full_collection_name, + op_query->full_collection_name_len)) { + return false; + } + + if (!_append_iovec_int32_t ( + *iovecs, capacity, count, &op_query->number_to_skip)) { + return false; + } + + if (!_append_iovec_int32_t ( + *iovecs, capacity, count, &op_query->number_to_return)) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_query->query, + (size_t) _int32_from_le (op_query->query))) { + return false; + } + + if (op_query->return_fields_selector) { + if (!_append_iovec_data ( + *iovecs, + capacity, + count, + op_query->return_fields_selector, + (size_t) _int32_from_le (op_query->return_fields_selector))) { + return false; + } + } + + return true; +} + +static bool +_append_iovec_op_get_more (mongoc_iovec_t **iovecs, + size_t *capacity, + size_t *count, + mcd_rpc_op_get_more *op_get_more, + const mongoc_iovec_t *header_iovecs) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (count); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (op_get_more); + BSON_ASSERT_PARAM (header_iovecs); + + _append_iovec_reserve_space_for (iovecs, capacity, header_iovecs, 4u); + + if (!_append_iovec_reserved_zero (*iovecs, capacity, count)) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_get_more->full_collection_name, + op_get_more->full_collection_name_len)) { + return false; + } + + if (!_append_iovec_int32_t ( + *iovecs, capacity, count, &op_get_more->number_to_return)) { + return false; + } + + if (!_append_iovec_int64_t ( + *iovecs, capacity, count, &op_get_more->cursor_id)) { + return false; + } + + return true; +} + +static bool +_append_iovec_op_delete (mongoc_iovec_t **iovecs, + size_t *capacity, + size_t *count, + mcd_rpc_op_delete *op_delete, + const mongoc_iovec_t *header_iovecs) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (count); + BSON_ASSERT_PARAM (op_delete); + BSON_ASSERT_PARAM (header_iovecs); + + _append_iovec_reserve_space_for (iovecs, capacity, header_iovecs, 4u); + + if (!_append_iovec_reserved_zero (*iovecs, capacity, count)) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_delete->full_collection_name, + op_delete->full_collection_name_len)) { + return false; + } + + if (!_append_iovec_int32_t (*iovecs, capacity, count, &op_delete->flags)) { + return false; + } + + if (!_append_iovec_data (*iovecs, + capacity, + count, + op_delete->selector, + (size_t) _int32_from_le (op_delete->selector))) { + return false; + } + + return true; +} + +static bool +_append_iovec_op_kill_cursors (mongoc_iovec_t **iovecs, + size_t *capacity, + size_t *count, + mcd_rpc_op_kill_cursors *op_kill_cursors, + const mongoc_iovec_t *header_iovecs) +{ + BSON_ASSERT_PARAM (iovecs); + BSON_ASSERT_PARAM (capacity); + BSON_ASSERT_PARAM (count); + BSON_ASSERT_PARAM (op_kill_cursors); + BSON_ASSERT_PARAM (header_iovecs); + + // Store value before conversion to little endian. + const int32_t number_of_cursor_ids = op_kill_cursors->number_of_cursor_ids; + + _append_iovec_reserve_space_for (iovecs, capacity, header_iovecs, 3u); + + if (!_append_iovec_reserved_zero (*iovecs, capacity, count)) { + return false; + } + + if (!_append_iovec_int32_t ( + *iovecs, capacity, count, &op_kill_cursors->number_of_cursor_ids)) { + return false; + } + + // Each cursorID must be converted to little endian. + for (int32_t i = 0; i < number_of_cursor_ids; ++i) { + int64_t *const cursor_id = op_kill_cursors->cursor_ids + i; + uint64_t storage; + memcpy (&storage, cursor_id, sizeof (int64_t)); + storage = BSON_UINT64_TO_LE (storage); + memcpy (cursor_id, &storage, sizeof (int64_t)); + } + + if (number_of_cursor_ids > 0 && + !_append_iovec_data (*iovecs, + capacity, + count, + op_kill_cursors->cursor_ids, + (size_t) number_of_cursor_ids * sizeof (int64_t))) { + return false; + } + + return true; +} + + +void * +mcd_rpc_message_to_iovecs (mcd_rpc_message *rpc, size_t *count) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT_PARAM (count); + + const int32_t op_code = rpc->msg_header.op_code; + + // Preallocated space for msgHeader fields. + mongoc_iovec_t header_iovecs[4]; + size_t capacity = 4u; + *count = 0u; + + (void) _append_iovec_int32_t ( + header_iovecs, &capacity, count, &rpc->msg_header.message_length); + (void) _append_iovec_int32_t ( + header_iovecs, &capacity, count, &rpc->msg_header.request_id); + (void) _append_iovec_int32_t ( + header_iovecs, &capacity, count, &rpc->msg_header.response_to); + (void) _append_iovec_int32_t ( + header_iovecs, &capacity, count, &rpc->msg_header.op_code); + + mongoc_iovec_t *iovecs = NULL; + mongoc_iovec_t *ret = NULL; + + // Fields may be converted to little endian even on failure, so consider the + // RPC object to be in an iovecs state from this point forward regardless of + // success or failure. + rpc->msg_header.is_in_iovecs_state = true; + + switch (op_code) { + case MONGOC_OP_CODE_COMPRESSED: + if (!_append_iovec_op_compressed ( + &iovecs, &capacity, count, &rpc->op_compressed, header_iovecs)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_MSG: { + if (!_append_iovec_op_msg ( + &iovecs, &capacity, count, &rpc->op_msg, header_iovecs)) { + goto fail; + } + break; + } + + case MONGOC_OP_CODE_REPLY: + if (!_append_iovec_op_reply ( + &iovecs, &capacity, count, &rpc->op_reply, header_iovecs)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_UPDATE: + if (!_append_iovec_op_update ( + &iovecs, &capacity, count, &rpc->op_update, header_iovecs)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_INSERT: + if (!_append_iovec_op_insert ( + &iovecs, &capacity, count, &rpc->op_insert, header_iovecs)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_QUERY: + if (!_append_iovec_op_query ( + &iovecs, &capacity, count, &rpc->op_query, header_iovecs)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_GET_MORE: + if (!_append_iovec_op_get_more ( + &iovecs, &capacity, count, &rpc->op_get_more, header_iovecs)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_DELETE: + if (!_append_iovec_op_delete ( + &iovecs, &capacity, count, &rpc->op_delete, header_iovecs)) { + goto fail; + } + break; + + case MONGOC_OP_CODE_KILL_CURSORS: + if (!_append_iovec_op_kill_cursors ( + &iovecs, &capacity, count, &rpc->op_kill_cursors, header_iovecs)) { + goto fail; + } + break; + + default: + goto fail; + } + + ret = iovecs; + iovecs = NULL; + +fail: + bson_free (iovecs); + + return ret; +} + +mcd_rpc_message * +mcd_rpc_message_new (void) +{ + mcd_rpc_message *const rpc = bson_malloc (sizeof (mcd_rpc_message)); + *rpc = (mcd_rpc_message){.msg_header = {0}}; + return rpc; +} + +static int32_t +_mcd_rpc_header_get_op_code_maybe_le (const mcd_rpc_message *rpc) +{ + BSON_ASSERT_PARAM (rpc); + + int32_t op_code = rpc->msg_header.op_code; + + // May already be in native endian. + switch (op_code) { + case MONGOC_OP_CODE_COMPRESSED: + case MONGOC_OP_CODE_MSG: + case MONGOC_OP_CODE_REPLY: + case MONGOC_OP_CODE_UPDATE: + case MONGOC_OP_CODE_INSERT: + case MONGOC_OP_CODE_QUERY: + case MONGOC_OP_CODE_GET_MORE: + case MONGOC_OP_CODE_DELETE: + case MONGOC_OP_CODE_KILL_CURSORS: + return op_code; + + default: + // May be in little endian. + op_code = _int32_from_le (&op_code); + + switch (op_code) { + case MONGOC_OP_CODE_COMPRESSED: + case MONGOC_OP_CODE_MSG: + case MONGOC_OP_CODE_REPLY: + case MONGOC_OP_CODE_UPDATE: + case MONGOC_OP_CODE_INSERT: + case MONGOC_OP_CODE_QUERY: + case MONGOC_OP_CODE_GET_MORE: + case MONGOC_OP_CODE_DELETE: + case MONGOC_OP_CODE_KILL_CURSORS: + return op_code; + + default: + // Doesn't seem to have been a valid opCode. + return rpc->msg_header.op_code; + } + } +} + +static void +_mcd_rpc_message_free_owners (mcd_rpc_message *rpc) +{ + BSON_ASSERT_PARAM (rpc); + + switch (_mcd_rpc_header_get_op_code_maybe_le (rpc)) { + case MONGOC_OP_CODE_MSG: + bson_free (rpc->op_msg.sections); + rpc->op_msg.sections = NULL; + return; + + case MONGOC_OP_CODE_KILL_CURSORS: + bson_free (rpc->op_kill_cursors.cursor_ids); + rpc->op_kill_cursors.cursor_ids = NULL; + return; + + case MONGOC_OP_CODE_COMPRESSED: + case MONGOC_OP_CODE_REPLY: + case MONGOC_OP_CODE_UPDATE: + case MONGOC_OP_CODE_INSERT: + case MONGOC_OP_CODE_QUERY: + case MONGOC_OP_CODE_GET_MORE: + case MONGOC_OP_CODE_DELETE: + return; + + default: + return; + } +} + +void +mcd_rpc_message_destroy (mcd_rpc_message *rpc) +{ + if (!rpc) { + return; + } + + _mcd_rpc_message_free_owners (rpc); + + bson_free ((void *) rpc); +} + +void +mcd_rpc_message_reset (mcd_rpc_message *rpc) +{ + BSON_ASSERT_PARAM (rpc); + + _mcd_rpc_message_free_owners (rpc); + + *rpc = (mcd_rpc_message){.msg_header = {0}}; +} + +void +mcd_rpc_message_set_length (mcd_rpc_message *rpc, int32_t value) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->msg_header.message_length = value; +} + +int32_t +mcd_rpc_header_get_message_length (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + return rpc->msg_header.message_length; +} + +int32_t +mcd_rpc_header_get_request_id (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + return rpc->msg_header.request_id; +} + +int32_t +mcd_rpc_header_get_response_to (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + return rpc->msg_header.response_to; +} + +int32_t +mcd_rpc_header_get_op_code (const mcd_rpc_message *rpc) +{ + BSON_ASSERT_PARAM (rpc); // Permit read access even if the RPC message object + // is in an iovecs state. + return rpc->msg_header.op_code; +} + +int32_t +mcd_rpc_header_set_message_length (mcd_rpc_message *rpc, int32_t message_length) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->msg_header.message_length = message_length; + return sizeof (message_length); +} + +int32_t +mcd_rpc_header_set_request_id (mcd_rpc_message *rpc, int32_t request_id) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->msg_header.request_id = request_id; + return sizeof (request_id); +} + +int32_t +mcd_rpc_header_set_response_to (mcd_rpc_message *rpc, int32_t response_to) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->msg_header.response_to = response_to; + return sizeof (response_to); +} + +int32_t +mcd_rpc_header_set_op_code (mcd_rpc_message *rpc, int32_t op_code) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + + _mcd_rpc_message_free_owners (rpc); + + rpc->msg_header.op_code = op_code; + return sizeof (op_code); +} + + +int32_t +mcd_rpc_op_compressed_get_original_opcode (const mcd_rpc_message *rpc) +{ + BSON_ASSERT_PARAM (rpc); // Permit read access even if the RPC message object + // is in an iovecs state. + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_COMPRESSED); + return rpc->op_compressed.original_opcode; +} + +int32_t +mcd_rpc_op_compressed_get_uncompressed_size (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_COMPRESSED); + return rpc->op_compressed.uncompressed_size; +} + +uint8_t +mcd_rpc_op_compressed_get_compressor_id (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_COMPRESSED); + return rpc->op_compressed.compressor_id; +} + +const void * +mcd_rpc_op_compressed_get_compressed_message (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_COMPRESSED); + return rpc->op_compressed.compressed_message; +} + +size_t +mcd_rpc_op_compressed_get_compressed_message_length (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_COMPRESSED); + return rpc->op_compressed.compressed_message_len; +} + +int32_t +mcd_rpc_op_compressed_set_original_opcode (mcd_rpc_message *rpc, + int32_t original_opcode) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_COMPRESSED); + rpc->op_compressed.original_opcode = original_opcode; + return sizeof (original_opcode); +} + +int32_t +mcd_rpc_op_compressed_set_uncompressed_size (mcd_rpc_message *rpc, + int32_t uncompressed_size) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_COMPRESSED); + rpc->op_compressed.uncompressed_size = uncompressed_size; + return sizeof (uncompressed_size); +} + +int32_t +mcd_rpc_op_compressed_set_compressor_id (mcd_rpc_message *rpc, + uint8_t compressor_id) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_COMPRESSED); + rpc->op_compressed.compressor_id = compressor_id; + return sizeof (compressor_id); +} + +int32_t +mcd_rpc_op_compressed_set_compressed_message (mcd_rpc_message *rpc, + const void *compressed_message, + size_t compressed_message_length) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_COMPRESSED); + BSON_ASSERT (bson_in_range_unsigned (int32_t, compressed_message_length)); + rpc->op_compressed.compressed_message = compressed_message; + rpc->op_compressed.compressed_message_len = compressed_message_length; + return (int32_t) compressed_message_length; +} + + +uint8_t +mcd_rpc_op_msg_section_get_kind (const mcd_rpc_message *rpc, size_t index) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + return rpc->op_msg.sections[index].kind; +} + +int32_t +mcd_rpc_op_msg_section_get_length (const mcd_rpc_message *rpc, size_t index) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + + const mcd_rpc_op_msg_section *const section = &rpc->op_msg.sections[index]; + + switch (section->kind) { + case 0: { // Body + return _int32_from_le (section->payload.body.bson); + } + + case 1: { // Document Sequence + return section->payload.document_sequence.section_len; + } + + default: + BSON_UNREACHABLE ("invalid section kind"); + } +} + +const char * +mcd_rpc_op_msg_section_get_identifier (const mcd_rpc_message *rpc, size_t index) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + + const mcd_rpc_op_msg_section *const section = &rpc->op_msg.sections[index]; + BSON_ASSERT (section->kind == 1); + return section->payload.document_sequence.identifier; +} + +const void * +mcd_rpc_op_msg_section_get_body (const mcd_rpc_message *rpc, size_t index) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + + const mcd_rpc_op_msg_section *const section = &rpc->op_msg.sections[index]; + BSON_ASSERT (section->kind == 0); + return section->payload.body.bson; +} + +const void * +mcd_rpc_op_msg_section_get_document_sequence (const mcd_rpc_message *rpc, + size_t index) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + + const mcd_rpc_op_msg_section *const section = &rpc->op_msg.sections[index]; + BSON_ASSERT (section->kind == 1); + return section->payload.document_sequence.bson_objects; +} + +size_t +mcd_rpc_op_msg_section_get_document_sequence_length (const mcd_rpc_message *rpc, + size_t index) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + + const mcd_rpc_op_msg_section *const section = &rpc->op_msg.sections[index]; + BSON_ASSERT (section->kind == 1); + return section->payload.document_sequence.bson_objects_len; +} + +int32_t +mcd_rpc_op_msg_section_set_kind (mcd_rpc_message *rpc, + size_t index, + uint8_t kind) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + rpc->op_msg.sections[index].kind = kind; + return sizeof (kind); +} + +int32_t +mcd_rpc_op_msg_section_set_length (mcd_rpc_message *rpc, + size_t index, + int32_t length) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + BSON_ASSERT (rpc->op_msg.sections[index].kind == 1); + rpc->op_msg.sections[index].payload.document_sequence.section_len = length; + return sizeof (length); +} + +int32_t +mcd_rpc_op_msg_section_set_identifier (mcd_rpc_message *rpc, + size_t index, + const char *identifier) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + BSON_ASSERT (rpc->op_msg.sections[index].kind == 1); + + const size_t identifier_len = identifier ? strlen (identifier) + 1u : 0u; + + rpc->op_msg.sections[index].payload.document_sequence.identifier = + identifier; + rpc->op_msg.sections[index].payload.document_sequence.identifier_len = + identifier_len; + + BSON_ASSERT (bson_in_range_unsigned (int32_t, identifier_len)); + return (int32_t) identifier_len; +} + +int32_t +mcd_rpc_op_msg_section_set_body (mcd_rpc_message *rpc, + size_t index, + const void *body) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + BSON_ASSERT (rpc->op_msg.sections[index].kind == 0); + + const int32_t section_len = body ? _int32_from_le (body) : 0; + + rpc->op_msg.sections[index].payload.body.bson = body; + rpc->op_msg.sections[index].payload.body.section_len = section_len; + + return section_len; +} + +int32_t +mcd_rpc_op_msg_section_set_document_sequence (mcd_rpc_message *rpc, + size_t index, + const void *document_sequence, + size_t document_sequence_length) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + BSON_ASSERT (index < rpc->op_msg.sections_count); + BSON_ASSERT (rpc->op_msg.sections[index].kind == 1); + + const size_t bson_objects_len = + document_sequence ? document_sequence_length : 0u; + + rpc->op_msg.sections[index].payload.document_sequence.bson_objects = + document_sequence; + rpc->op_msg.sections[index].payload.document_sequence.bson_objects_len = + bson_objects_len; + + BSON_ASSERT (bson_in_range_unsigned (int32_t, document_sequence_length)); + return (int32_t) bson_objects_len; +} + + +uint32_t +mcd_rpc_op_msg_get_flag_bits (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + return rpc->op_msg.flag_bits; +} + +size_t +mcd_rpc_op_msg_get_sections_count (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + return rpc->op_msg.sections_count; +} + +const uint32_t * +mcd_rpc_op_msg_get_checksum (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + return rpc->op_msg.checksum_set ? &rpc->op_msg.checksum : NULL; +} + +int32_t +mcd_rpc_op_msg_set_flag_bits (mcd_rpc_message *rpc, uint32_t flag_bits) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + rpc->op_msg.flag_bits = flag_bits; + return sizeof (flag_bits); +} + +void +mcd_rpc_op_msg_set_sections_count (mcd_rpc_message *rpc, size_t section_count) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + + rpc->op_msg.sections = bson_realloc ( + rpc->op_msg.sections, section_count * sizeof (mcd_rpc_op_msg_section)); + rpc->op_msg.sections_count = section_count; +} + +int32_t +mcd_rpc_op_msg_set_checksum (mcd_rpc_message *rpc, uint32_t checksum) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_MSG); + rpc->op_msg.checksum = checksum; + rpc->op_msg.checksum_set = true; + return sizeof (checksum); +} + + +int32_t +mcd_rpc_op_reply_get_response_flags (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_REPLY); + return rpc->op_reply.response_flags; +} + +int64_t +mcd_rpc_op_reply_get_cursor_id (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_REPLY); + return rpc->op_reply.cursor_id; +} + +int32_t +mcd_rpc_op_reply_get_starting_from (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_REPLY); + return rpc->op_reply.starting_from; +} + +int32_t +mcd_rpc_op_reply_get_number_returned (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_REPLY); + return rpc->op_reply.number_returned; +} + +const void * +mcd_rpc_op_reply_get_documents (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_REPLY); + return rpc->op_reply.documents_len > 0 ? rpc->op_reply.documents : NULL; +} + +size_t +mcd_rpc_op_reply_get_documents_len (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_REPLY); + return rpc->op_reply.documents_len; +} + +int32_t +mcd_rpc_op_reply_set_response_flags (mcd_rpc_message *rpc, + int32_t response_flags) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->op_reply.response_flags = response_flags; + return sizeof (response_flags); +} + +int32_t +mcd_rpc_op_reply_set_cursor_id (mcd_rpc_message *rpc, int64_t cursor_id) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->op_reply.cursor_id = cursor_id; + return sizeof (cursor_id); +} + +int32_t +mcd_rpc_op_reply_set_starting_from (mcd_rpc_message *rpc, int32_t starting_from) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->op_reply.starting_from = starting_from; + return sizeof (starting_from); +} + +int32_t +mcd_rpc_op_reply_set_number_returned (mcd_rpc_message *rpc, + int32_t number_returned) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->op_reply.number_returned = number_returned; + return sizeof (number_returned); +} + +int32_t +mcd_rpc_op_reply_set_documents (mcd_rpc_message *rpc, + const void *documents, + size_t documents_len) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + + rpc->op_reply.documents = documents; + rpc->op_reply.documents_len = documents_len; + + BSON_ASSERT (bson_in_range_unsigned (int32_t, documents_len)); + return (int32_t) documents_len; +} + + +const char * +mcd_rpc_op_update_get_full_collection_name (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_UPDATE); + return rpc->op_update.full_collection_name; +} + +int32_t +mcd_rpc_op_update_get_flags (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_UPDATE); + return rpc->op_update.flags; +} + +const void * +mcd_rpc_op_update_get_selector (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_UPDATE); + return rpc->op_update.selector; +} + +const void * +mcd_rpc_op_update_get_update (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_UPDATE); + return rpc->op_update.update; +} + +int32_t +mcd_rpc_op_update_set_full_collection_name (mcd_rpc_message *rpc, + const char *full_collection_name) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + + const size_t length = + full_collection_name ? strlen (full_collection_name) + 1u : 0u; + + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_UPDATE); + rpc->op_update.full_collection_name = full_collection_name; + rpc->op_update.full_collection_name_len = length; + + BSON_ASSERT (bson_in_range_unsigned (int32_t, length)); + return (int32_t) length; +} + +int32_t +mcd_rpc_op_update_set_flags (mcd_rpc_message *rpc, int32_t flags) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->op_update.flags = flags; + return sizeof (flags); +} + +int32_t +mcd_rpc_op_update_set_selector (mcd_rpc_message *rpc, const void *selector) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->op_update.selector = selector; + return selector ? _int32_from_le (selector) : 0; +} + +int32_t +mcd_rpc_op_update_set_update (mcd_rpc_message *rpc, const void *update) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + rpc->op_update.update = update; + return update ? _int32_from_le (update) : 0; +} + + +int32_t +mcd_rpc_op_insert_get_flags (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_INSERT); + return rpc->op_insert.flags; +} + +const char * +mcd_rpc_op_insert_get_full_collection_name (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_INSERT); + return rpc->op_insert.full_collection_name; +} + +const void * +mcd_rpc_op_insert_get_documents (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_INSERT); + return rpc->op_insert.documents; +} + +size_t +mcd_rpc_op_insert_get_documents_len (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_INSERT); + return rpc->op_insert.documents_len; +} + +int32_t +mcd_rpc_op_insert_set_flags (mcd_rpc_message *rpc, int32_t flags) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_INSERT); + rpc->op_insert.flags = flags; + return sizeof (flags); +} + +int32_t +mcd_rpc_op_insert_set_full_collection_name (mcd_rpc_message *rpc, + const char *full_collection_name) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_INSERT); + + const size_t length = + full_collection_name ? strlen (full_collection_name) + 1u : 0u; + + rpc->op_insert.full_collection_name = full_collection_name; + rpc->op_insert.full_collection_name_len = length; + + BSON_ASSERT (bson_in_range_unsigned (int32_t, length)); + return (int32_t) length; +} + +int32_t +mcd_rpc_op_insert_set_documents (mcd_rpc_message *rpc, + const void *documents, + size_t documents_len) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_INSERT); + + rpc->op_insert.documents = documents; + rpc->op_insert.documents_len = documents_len; + + BSON_ASSERT (bson_in_range_unsigned (int32_t, documents_len)); + return (int32_t) documents_len; +} + + +int32_t +mcd_rpc_op_query_get_flags (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + return rpc->op_query.flags; +} + +const char * +mcd_rpc_op_query_get_full_collection_name (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + return rpc->op_query.full_collection_name; +} + +int32_t +mcd_rpc_op_query_get_number_to_skip (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + return rpc->op_query.number_to_skip; +} + +int32_t +mcd_rpc_op_query_get_number_to_return (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + return rpc->op_query.number_to_return; +} + +const void * +mcd_rpc_op_query_get_query (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + return rpc->op_query.query; +} + +const void * +mcd_rpc_op_query_get_return_fields_selector (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + return rpc->op_query.return_fields_selector; +} + +int32_t +mcd_rpc_op_query_set_flags (mcd_rpc_message *rpc, int32_t flags) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + rpc->op_query.flags = flags; + return sizeof (flags); +} + +int32_t +mcd_rpc_op_query_set_full_collection_name (mcd_rpc_message *rpc, + const char *full_collection_name) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + + const size_t length = + full_collection_name ? strlen (full_collection_name) + 1u : 0u; + + rpc->op_query.full_collection_name = full_collection_name; + rpc->op_query.full_collection_name_len = length; + + BSON_ASSERT (bson_in_range_unsigned (int32_t, length)); + return (int32_t) length; +} + +int32_t +mcd_rpc_op_query_set_number_to_skip (mcd_rpc_message *rpc, + int32_t number_to_skip) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + rpc->op_query.number_to_skip = number_to_skip; + return sizeof (number_to_skip); +} + +int32_t +mcd_rpc_op_query_set_number_to_return (mcd_rpc_message *rpc, + int32_t number_to_return) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + rpc->op_query.number_to_return = number_to_return; + return sizeof (number_to_return); +} + +int32_t +mcd_rpc_op_query_set_query (mcd_rpc_message *rpc, const void *query) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + rpc->op_query.query = query; + return _int32_from_le (query); +} + +int32_t +mcd_rpc_op_query_set_return_fields_selector (mcd_rpc_message *rpc, + const void *return_fields_selector) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_QUERY); + rpc->op_query.return_fields_selector = return_fields_selector; + return return_fields_selector ? _int32_from_le (return_fields_selector) : 0; +} + + +const char * +mcd_rpc_op_get_more_get_full_collection_name (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_GET_MORE); + return rpc->op_get_more.full_collection_name; +} + +int32_t +mcd_rpc_op_get_more_get_number_to_return (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_GET_MORE); + return rpc->op_get_more.number_to_return; +} + +int64_t +mcd_rpc_op_get_more_get_cursor_id (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_GET_MORE); + return rpc->op_get_more.cursor_id; +} + +int32_t +mcd_rpc_op_get_more_set_full_collection_name (mcd_rpc_message *rpc, + const char *full_collection_name) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_GET_MORE); + + const size_t length = + full_collection_name ? strlen (full_collection_name) + 1u : 0u; + + rpc->op_get_more.full_collection_name = full_collection_name; + rpc->op_get_more.full_collection_name_len = length; + + BSON_ASSERT (bson_in_range_unsigned (int32_t, length)); + return (int32_t) length; +} + +int32_t +mcd_rpc_op_get_more_set_number_to_return (mcd_rpc_message *rpc, + int32_t number_to_return) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_GET_MORE); + rpc->op_get_more.number_to_return = number_to_return; + return sizeof (number_to_return); +} + +int32_t +mcd_rpc_op_get_more_set_cursor_id (mcd_rpc_message *rpc, int64_t cursor_id) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_GET_MORE); + rpc->op_get_more.cursor_id = cursor_id; + return sizeof (cursor_id); +} + + +const char * +mcd_rpc_op_delete_get_full_collection_name (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_DELETE); + return rpc->op_delete.full_collection_name; +} + +int32_t +mcd_rpc_op_delete_get_flags (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + return rpc->op_delete.flags; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_DELETE); +} + +const void * +mcd_rpc_op_delete_get_selector (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_DELETE); + return rpc->op_delete.selector; +} + +int32_t +mcd_rpc_op_delete_set_full_collection_name (mcd_rpc_message *rpc, + const char *full_collection_name) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_DELETE); + + const size_t length = + full_collection_name ? strlen (full_collection_name) + 1u : 0u; + + rpc->op_delete.full_collection_name = full_collection_name; + rpc->op_delete.full_collection_name_len = length; + + BSON_ASSERT (bson_in_range_unsigned (int32_t, length)); + return (int32_t) length; +} + +int32_t +mcd_rpc_op_delete_set_flags (mcd_rpc_message *rpc, int32_t flags) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_DELETE); + rpc->op_delete.flags = flags; + return sizeof (flags); +} + +int32_t +mcd_rpc_op_delete_set_selector (mcd_rpc_message *rpc, const void *selector) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_DELETE); + rpc->op_delete.selector = selector; + return selector ? _int32_from_le (selector) : 0; +} + + +int32_t +mcd_rpc_op_kill_cursors_get_number_of_cursor_ids (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_KILL_CURSORS); + return rpc->op_kill_cursors.number_of_cursor_ids; +} + +const int64_t * +mcd_rpc_op_kill_cursors_get_cursor_ids (const mcd_rpc_message *rpc) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_KILL_CURSORS); + return rpc->op_kill_cursors.number_of_cursor_ids > 0 + ? rpc->op_kill_cursors.cursor_ids + : NULL; +} + +int32_t +mcd_rpc_op_kill_cursors_set_cursor_ids (mcd_rpc_message *rpc, + const int64_t *cursor_ids, + int32_t number_of_cursor_ids) +{ + ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS; + BSON_ASSERT (rpc->msg_header.op_code == MONGOC_OP_CODE_KILL_CURSORS); + BSON_ASSERT (bson_cmp_less_su (number_of_cursor_ids, + (size_t) INT32_MAX / sizeof (int64_t))); + + const size_t cursor_ids_length = + (size_t) number_of_cursor_ids * sizeof (int64_t); + + rpc->op_kill_cursors.number_of_cursor_ids = number_of_cursor_ids; + + bson_free (rpc->op_kill_cursors.cursor_ids); + + if (number_of_cursor_ids > 0) { + rpc->op_kill_cursors.cursor_ids = bson_malloc (cursor_ids_length); + memcpy (rpc->op_kill_cursors.cursor_ids, cursor_ids, cursor_ids_length); + } else { + rpc->op_kill_cursors.cursor_ids = NULL; + } + + return (int32_t) sizeof (int32_t) + (int32_t) cursor_ids_length; +} diff --git a/src/mongoc/mcd-rpc.h b/src/mongoc/mcd-rpc.h new file mode 100644 index 00000000..ba66ea7a --- /dev/null +++ b/src/mongoc/mcd-rpc.h @@ -0,0 +1,780 @@ +/* + * Copyright 2023 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#if !defined(MCD_RPC_H_INCLUDED) +#define MCD_RPC_H_INCLUDED + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef union _mcd_rpc_message mcd_rpc_message; + + +// See: https://www.mongodb.com/docs/manual/reference/mongodb-wire-protocol +#define MONGOC_OP_CODE_NONE INT32_C (0) +#define MONGOC_OP_CODE_COMPRESSED INT32_C (2012) +#define MONGOC_OP_CODE_MSG INT32_C (2013) + +#define MONGOC_OP_COMPRESSED_COMPRESSOR_ID_NOOP UINT8_C (0) +#define MONGOC_OP_COMPRESSED_COMPRESSOR_ID_SNAPPY UINT8_C (1) +#define MONGOC_OP_COMPRESSED_COMPRESSOR_ID_ZLIB UINT8_C (2) +#define MONGOC_OP_COMPRESSED_COMPRESSOR_ID_ZSTD UINT8_C (3) + +#define MONGOC_OP_MSG_FLAG_NONE UINT32_C (0) +#define MONGOC_OP_MSG_FLAG_CHECKSUM_PRESENT (UINT32_C (0x01) << 0) +#define MONGOC_OP_MSG_FLAG_MORE_TO_COME (UINT32_C (0x01) << 1) +#define MONGOC_OP_MSG_FLAG_EXHAUST_ALLOWED (UINT32_C (0x01) << 16) + + +// See: https://www.mongodb.com/docs/manual/legacy-opcodes/ +#define MONGOC_OP_CODE_REPLY INT32_C (1) +#define MONGOC_OP_CODE_UPDATE INT32_C (2001) +#define MONGOC_OP_CODE_INSERT INT32_C (2002) +#define MONGOC_OP_CODE_QUERY INT32_C (2004) +#define MONGOC_OP_CODE_GET_MORE INT32_C (2005) +#define MONGOC_OP_CODE_DELETE INT32_C (2006) +#define MONGOC_OP_CODE_KILL_CURSORS INT32_C (2007) + +#define MONGOC_OP_REPLY_RESPONSE_FLAG_NONE INT32_C (0) +#define MONGOC_OP_REPLY_RESPONSE_FLAG_CURSOR_NOT_FOUND (INT32_C (0x01) << 0) +#define MONGOC_OP_REPLY_RESPONSE_FLAG_QUERY_FAILURE (INT32_C (0x01) << 1) +#define MONGOC_OP_REPLY_RESPONSE_FLAG_SHARD_CONFIG_STALE (INT32_C (0x01) << 2) +#define MONGOC_OP_REPLY_RESPONSE_FLAG_AWAIT_CAPABLE (INT32_C (0x01) << 3) + +#define MONGOC_OP_UPDATE_FLAG_NONE INT32_C (0) +#define MONGOC_OP_UPDATE_FLAG_UPSERT (INT32_C (0x01) << 0) +#define MONGOC_OP_UPDATE_FLAG_MULTI_UPDATE (INT32_C (0x01) << 1) + +#define MONGOC_OP_INSERT_FLAG_NONE INT32_C (0) +#define MONGOC_OP_INSERT_FLAG_CONTINUE_ON_ERROR (INT32_C (0x01) << 0) + +#define MONGOC_OP_QUERY_FLAG_NONE INT32_C (0) +#define MONGOC_OP_QUERY_FLAG_TAILABLE_CURSOR (INT32_C (0x01) << 1) +#define MONGOC_OP_QUERY_FLAG_SECONDARY_OK (INT32_C (0x01) << 2) +#define MONGOC_OP_QUERY_FLAG_OPLOG_REPLAY (INT32_C (0x01) << 3) +#define MONGOC_OP_QUERY_FLAG_NO_CURSOR_TIMEOUT (INT32_C (0x01) << 4) +#define MONGOC_OP_QUERY_FLAG_AWAIT_DATA (INT32_C (0x01) << 5) +#define MONGOC_OP_QUERY_FLAG_EXHAUST (INT32_C (0x01) << 6) +#define MONGOC_OP_QUERY_FLAG_PARTIAL (INT32_C (0x01) << 7) + +#define MONGOC_OP_DELETE_FLAG_NONE INT32_C (0) +#define MONGOC_OP_DELETE_FLAG_SINGLE_REMOVE (INT32_C (0x01) << 0) + + +// Convert the given array of bytes into an RPC message object. The RPC message +// object must be freed by `mcd_rpc_message_destroy`. +// +// data: an array of `length` bytes. +// data_end: if not `NULL`, `*data_end` is set to one past the last byte of +// valid input data. Useful for diagnosing failures. +// +// Note: the fields of the RPC message object are automatically converted from +// little endian to native endian. +// +// Returns the new RPC message object on success. Returns `NULL` on failure. +mcd_rpc_message * +mcd_rpc_message_from_data (const void *data, + size_t length, + const void **data_end); + +// The in-place version of `mcd_rpc_message_from_data`. +// +// rpc: an RPC message object in an initialized state. +// +// Returns `true` on success. Returns `false` on failure. +bool +mcd_rpc_message_from_data_in_place (mcd_rpc_message *rpc, + const void *data, + size_t length, + const void **data_end); + +// Convert the given RPC message object into an array of iovec structures, +// putting the RPC message object in an iovecs state. The return value must be +// freed by `bson_free`. +// +// Unless otherwise specified, it is undefined behavior to access any RPC +// message field when the object is in an iovecs state. Use +// `mcd_rpc_message_reset` to return the object to an initialized state before +// further reuse. +// +// The data layout of the iovec structures is consistent with the definition of +// `mongoc_iovec_t` as defined in ``. +// +// rpc: a valid RPC message object whose fields are in native endian. +// length: if not `NULL`, `*length` is set to the number of iovec structures in +// the array. +// +// Returns the array of iovec structures on success. Returns `NULL` on failure. +void * +mcd_rpc_message_to_iovecs (mcd_rpc_message *rpc, size_t *count); + +// Return an RPC message object in an initialized state whose fields will be set +// manually. The return value must be freed by `mcd_rpc_message_destroy`. +mcd_rpc_message * +mcd_rpc_message_new (void); + +// Destroy the given RPC message object. +void +mcd_rpc_message_destroy (mcd_rpc_message *rpc); + +// Restore the given RPC message object to an initialized state. +void +mcd_rpc_message_reset (mcd_rpc_message *rpc); + +// Set the message length for the given RPC message object. Expected to be used +// in conjunction with the return values of setters. +void +mcd_rpc_message_set_length (mcd_rpc_message *rpc, int32_t value); + +// Get the msgHeader.messageLength field. +int32_t +mcd_rpc_header_get_message_length (const mcd_rpc_message *rpc); + +// Get the msgHeader.requestId field. +int32_t +mcd_rpc_header_get_request_id (const mcd_rpc_message *rpc); + +// Get the msgHeader.responseTo field. +int32_t +mcd_rpc_header_get_response_to (const mcd_rpc_message *rpc); + +// Get the msgHeader.opCode field. +// +// This function may be called even if the RPC message is in an iovecs state. +int32_t +mcd_rpc_header_get_op_code (const mcd_rpc_message *rpc); + +// Set the msgHeader.messageLength field. +// +// Returns the length of the field as part of msgHeader.messageLength. +int32_t +mcd_rpc_header_set_message_length (mcd_rpc_message *rpc, + int32_t message_length); + +// Set the msgHeader.requestId field. +// +// Returns the length of the field as part of msgHeader.messageLength. +int32_t +mcd_rpc_header_set_request_id (mcd_rpc_message *rpc, int32_t request_id); + +// Set the msgHeader.responseTo field. +// +// Returns the length of the field as part of msgHeader.messageLength. +int32_t +mcd_rpc_header_set_response_to (mcd_rpc_message *rpc, int32_t response_to); + +// Set the msgHeader.opCode field. +// +// Note: the msgHeader.opCode field may be set more than once. +// +// Returns the length of the field as part of msgHeader.messageLength. +int32_t +mcd_rpc_header_set_op_code (mcd_rpc_message *rpc, int32_t op_code); + + +// Get the OP_COMPRESSED originalOpcode field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_COMPRESSED. +// +// This function may be called even if the RPC message is in an iovecs state. +int32_t +mcd_rpc_op_compressed_get_original_opcode (const mcd_rpc_message *rpc); + +// Get the OP_COMPRESSED uncompressedSize field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_COMPRESSED. +int32_t +mcd_rpc_op_compressed_get_uncompressed_size (const mcd_rpc_message *rpc); + +// Get the OP_COMPRESSED compressorId field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_COMPRESSED. +uint8_t +mcd_rpc_op_compressed_get_compressor_id (const mcd_rpc_message *rpc); + +// Get the OP_COMPRESSED compressedMessage field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_COMPRESSED. +const void * +mcd_rpc_op_compressed_get_compressed_message (const mcd_rpc_message *rpc); + +// Get the length of the OP_COMPRESSED compressedMessage field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_COMPRESSED. +size_t +mcd_rpc_op_compressed_get_compressed_message_length ( + const mcd_rpc_message *rpc); + +// Set the OP_COMPRESSED originalOpcode field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_COMPRESSED. +int32_t +mcd_rpc_op_compressed_set_original_opcode (mcd_rpc_message *rpc, + int32_t original_opcode); + +// Set the OP_COMPRESSED uncompressedSize field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_COMPRESSED. +int32_t +mcd_rpc_op_compressed_set_uncompressed_size (mcd_rpc_message *rpc, + int32_t uncompressed_size); + +// Set the OP_COMPRESSED compressorId field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_COMPRESSED. +int32_t +mcd_rpc_op_compressed_set_compressor_id (mcd_rpc_message *rpc, + uint8_t compressor_id); + +// Set the OP_COMPRESSED compressedMessage field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_COMPRESSED. +int32_t +mcd_rpc_op_compressed_set_compressed_message (mcd_rpc_message *rpc, + const void *compressed_message, + size_t compressed_message_length); + + +// Get the kind byte for the OP_MSG section at the given index. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +uint8_t +mcd_rpc_op_msg_section_get_kind (const mcd_rpc_message *rpc, size_t index); + +// Get the length of the OP_MSG section at the given index. +// +// If the section kind is 0, returns the length of the single BSON object. +// If the section kind is 1, returns the total length of the section. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +int32_t +mcd_rpc_op_msg_section_get_length (const mcd_rpc_message *rpc, size_t index); + +// Get the document sequence identifier of the OP_MSG document sequence section +// at the given index. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +// The section kind at the given index MUST equal 1. +const char * +mcd_rpc_op_msg_section_get_identifier (const mcd_rpc_message *rpc, + size_t index); + +// Get a pointer to the beginning of the single BSON object of the OP_MSG body +// section at the given index. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +// The section kind at the given index MUST equal 0. +const void * +mcd_rpc_op_msg_section_get_body (const mcd_rpc_message *rpc, size_t index); + +// Get a pointer to the beginning of the document sequence of the OP_MSG +// document sequence section at the given index. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +// The section kind at the given index MUST equal 1. +const void * +mcd_rpc_op_msg_section_get_document_sequence (const mcd_rpc_message *rpc, + size_t index); + +// Get the length of the document sequence of the OP_MSG document sequence +// section at the given index. +// +// Note: the length is the number of bytes, NOT the number of documents. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +// The section kind at the given index MUST equal 1. +size_t +mcd_rpc_op_msg_section_get_document_sequence_length (const mcd_rpc_message *rpc, + size_t index); + +// Set the kind byte for the OP_MSG section at the given index. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +int32_t +mcd_rpc_op_msg_section_set_kind (mcd_rpc_message *rpc, + size_t index, + uint8_t kind); + +// Set the length of the OP_MSG document sequence section at the given index. +// +// Note: the section length of an OP_MSG body section is equal to the length +// of the single BSON object, thus does not require a seperate setter. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +// The section kind at the given index MUST equal 1. +int32_t +mcd_rpc_op_msg_section_set_length (mcd_rpc_message *rpc, + size_t index, + int32_t length); + +// Set the document sequence identifier of the OP_MSG document sequence section +// at the given index. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +// The section kind at the given index MUST equal 1. +int32_t +mcd_rpc_op_msg_section_set_identifier (mcd_rpc_message *rpc, + size_t index, + const char *identifier); + +// Set the BSON object for the OP_MSG body section at the given index. +// +// Note: the section length of an OP_MSG body section is equal to the length +// of the single BSON object, thus does not require a seperate setter. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +// The section kind at the given index MUST equal 0. +int32_t +mcd_rpc_op_msg_section_set_body (mcd_rpc_message *rpc, + size_t index, + const void *body); + +// Set the document sequence for the OP_MSG document sequence section at the +// given index. +// +// `document_sequence_length` MUST equal the length in bytes of the document +// sequence. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +// The given index MUST be a valid index into the OP_MSG sections array. +// The section kind at the given index MUST equal 1. +int32_t +mcd_rpc_op_msg_section_set_document_sequence (mcd_rpc_message *rpc, + size_t index, + const void *document_sequence, + size_t document_sequence_length); + + +// Get the OP_MSG flagBits field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +uint32_t +mcd_rpc_op_msg_get_flag_bits (const mcd_rpc_message *rpc); + +// Get the number of sections in the OP_MSG sections array. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +size_t +mcd_rpc_op_msg_get_sections_count (const mcd_rpc_message *rpc); + +// Get the OP_MSG checksum field. +// +// Returns `NULL` if the field is not set. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +const uint32_t * +mcd_rpc_op_msg_get_checksum (const mcd_rpc_message *rpc); + +// Set the OP_MSG flagBits field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +int32_t +mcd_rpc_op_msg_set_flag_bits (mcd_rpc_message *rpc, uint32_t flag_bits); + +// Set the number of sections in the OP_MSG section array. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +void +mcd_rpc_op_msg_set_sections_count (mcd_rpc_message *rpc, size_t section_count); + +// Set the OP_MSG checksum field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_MSG. +int32_t +mcd_rpc_op_msg_set_checksum (mcd_rpc_message *rpc, uint32_t checksum); + + +// Get the OP_REPLY responseFlags field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +int32_t +mcd_rpc_op_reply_get_response_flags (const mcd_rpc_message *rpc); + +// Get the OP_REPLY cursorID field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +int64_t +mcd_rpc_op_reply_get_cursor_id (const mcd_rpc_message *rpc); + +// Get the OP_REPLY startingFrom field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +int32_t +mcd_rpc_op_reply_get_starting_from (const mcd_rpc_message *rpc); + +// Get the OP_REPLY numberReturned field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +int32_t +mcd_rpc_op_reply_get_number_returned (const mcd_rpc_message *rpc); + +// Get a pointer to the beginning of the OP_REPLY documents array. +// +// Returns `NULL` if the OP_REPLY numberReturned field equals 0. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +const void * +mcd_rpc_op_reply_get_documents (const mcd_rpc_message *rpc); + +// Get the length of the OP_REPLY documents array. +// +// Note: the length is the number of bytes, NOT the number of documents. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +size_t +mcd_rpc_op_reply_get_documents_len (const mcd_rpc_message *rpc); + +// Set the OP_REPLY responseFlags field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +int32_t +mcd_rpc_op_reply_set_response_flags (mcd_rpc_message *rpc, + int32_t response_flags); + +// Set the OP_REPLY cursorID field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +int32_t +mcd_rpc_op_reply_set_cursor_id (mcd_rpc_message *rpc, int64_t cursor_id); + +// Set the OP_REPLY startingFrom field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +int32_t +mcd_rpc_op_reply_set_starting_from (mcd_rpc_message *rpc, + int32_t starting_from); + +// Set the OP_REPLY numberReturned field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +int32_t +mcd_rpc_op_reply_set_number_returned (mcd_rpc_message *rpc, + int32_t number_returned); + +// Set the OP_REPLY documents field. +// +// `documents_len` MUST equal the length in bytes of the documents array. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_REPLY. +int32_t +mcd_rpc_op_reply_set_documents (mcd_rpc_message *rpc, + const void *documents, + size_t documents_len); + + +// Get the OP_UPDATE fullCollectionName field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_UPDATE. +const char * +mcd_rpc_op_update_get_full_collection_name (const mcd_rpc_message *rpc); + +// Get the OP_UPDATE flags field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_UPDATE. +int32_t +mcd_rpc_op_update_get_flags (const mcd_rpc_message *rpc); + +// Get the OP_UPDATE selector field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_UPDATE. +const void * +mcd_rpc_op_update_get_selector (const mcd_rpc_message *rpc); + +// Get the OP_UPDATE update field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_UPDATE. +const void * +mcd_rpc_op_update_get_update (const mcd_rpc_message *rpc); + +// Set the OP_UPDATE fullCollectionName field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_UPDATE. +int32_t +mcd_rpc_op_update_set_full_collection_name (mcd_rpc_message *rpc, + const char *full_collection_name); + +// Set the OP_UPDATE flags field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_UPDATE. +int32_t +mcd_rpc_op_update_set_flags (mcd_rpc_message *rpc, int32_t flags); + +// Set the OP_UPDATE selector field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_UPDATE. +int32_t +mcd_rpc_op_update_set_selector (mcd_rpc_message *rpc, const void *selector); + +// Set the OP_UPDATE update field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_UPDATE. +int32_t +mcd_rpc_op_update_set_update (mcd_rpc_message *rpc, const void *update); + + +// Get the OP_INSERT flags field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_INSERT. +int32_t +mcd_rpc_op_insert_get_flags (const mcd_rpc_message *rpc); + +// Get the OP_INSERT fullCollectionName field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_INSERT. +const char * +mcd_rpc_op_insert_get_full_collection_name (const mcd_rpc_message *rpc); + +// Get a pointer to the beginning of the OP_INSERT documents array. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_INSERT. +const void * +mcd_rpc_op_insert_get_documents (const mcd_rpc_message *rpc); + +// Get the length of the OP_INSERT documents array. +// +// Note: the length is the number of bytes, NOT the number of documents. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_INSERT. +size_t +mcd_rpc_op_insert_get_documents_len (const mcd_rpc_message *rpc); + +// Set the OP_INSERT flags field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_INSERT. +int32_t +mcd_rpc_op_insert_set_flags (mcd_rpc_message *rpc, int32_t flags); + +// Set the OP_INSERT fullCollectionName field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_INSERT. +int32_t +mcd_rpc_op_insert_set_full_collection_name (mcd_rpc_message *rpc, + const char *full_collection_name); + +// Set the OP_INSERT documents array. +// +// `documents_len` MUST equal the length in bytes of the documents array. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_INSERT. +int32_t +mcd_rpc_op_insert_set_documents (mcd_rpc_message *rpc, + const void *documents, + size_t documents_len); + + +// Get the OP_QUERY flags field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +int32_t +mcd_rpc_op_query_get_flags (const mcd_rpc_message *rpc); + +// Get the OP_QUERY fullCollectionName field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +const char * +mcd_rpc_op_query_get_full_collection_name (const mcd_rpc_message *rpc); + +// Get the OP_QUERY numberToSkip field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +int32_t +mcd_rpc_op_query_get_number_to_skip (const mcd_rpc_message *rpc); + +// Get the OP_QUERY numberToReturn field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +int32_t +mcd_rpc_op_query_get_number_to_return (const mcd_rpc_message *rpc); + +// Get the OP_QUERY query field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +const void * +mcd_rpc_op_query_get_query (const mcd_rpc_message *rpc); + +// Get the OP_QUERY returnFieldsSelector field. +// +// Returns `NULL` if the field is not set. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +const void * +mcd_rpc_op_query_get_return_fields_selector (const mcd_rpc_message *rpc); + +// Set the OP_QUERY flags field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +int32_t +mcd_rpc_op_query_set_flags (mcd_rpc_message *rpc, int32_t flags); + +// Set the OP_QUERY fullCollectionName field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +int32_t +mcd_rpc_op_query_set_full_collection_name (mcd_rpc_message *rpc, + const char *full_collection_name); + +// Set the OP_QUERY numberToSkip field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +int32_t +mcd_rpc_op_query_set_number_to_skip (mcd_rpc_message *rpc, + int32_t number_to_skip); + +// Set the OP_QUERY numberToReturn field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +int32_t +mcd_rpc_op_query_set_number_to_return (mcd_rpc_message *rpc, + int32_t number_to_return); + +// Set the OP_QUERY query field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +int32_t +mcd_rpc_op_query_set_query (mcd_rpc_message *rpc, const void *query); + +// Set the OP_QUERY returnFieldsSelector field. +// +// Note: `return_fields_selector` may be `NULL` to unset the field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_QUERY. +int32_t +mcd_rpc_op_query_set_return_fields_selector ( + mcd_rpc_message *rpc, const void *return_fields_selector); + + +// Get the OP_GET_MORE fullCollectionName field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_GET_MORE. +const char * +mcd_rpc_op_get_more_get_full_collection_name (const mcd_rpc_message *rpc); + +// Get the OP_GET_MORE numberToReturn field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_GET_MORE. +int32_t +mcd_rpc_op_get_more_get_number_to_return (const mcd_rpc_message *rpc); + +// Get the OP_GET_MORE cursorID field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_GET_MORE. +int64_t +mcd_rpc_op_get_more_get_cursor_id (const mcd_rpc_message *rpc); + +// Set the OP_GET_MORE fullCollectionName field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_GET_MORE. +int32_t +mcd_rpc_op_get_more_set_full_collection_name (mcd_rpc_message *rpc, + const char *full_collection_name); + +// Set the OP_GET_MORE numberToReturn field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_GET_MORE. +int32_t +mcd_rpc_op_get_more_set_number_to_return (mcd_rpc_message *rpc, + int32_t number_to_return); + +// Set the OP_GET_MORE cursorID field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_GET_MORE. +int32_t +mcd_rpc_op_get_more_set_cursor_id (mcd_rpc_message *rpc, int64_t cursor_id); + + +// Get the OP_DELETE fullCollectionName field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_DELETE. +const char * +mcd_rpc_op_delete_get_full_collection_name (const mcd_rpc_message *rpc); + +// Get the OP_DELETE flags field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_DELETE. +int32_t +mcd_rpc_op_delete_get_flags (const mcd_rpc_message *rpc); + +// Get the OP_DELETE selector field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_DELETE. +const void * +mcd_rpc_op_delete_get_selector (const mcd_rpc_message *rpc); + +// Set the OP_DELETE fullCollectionName field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_DELETE. +int32_t +mcd_rpc_op_delete_set_full_collection_name (mcd_rpc_message *rpc, + const char *full_collection_name); + +// Set the OP_DELETE flags field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_DELETE. +int32_t +mcd_rpc_op_delete_set_flags (mcd_rpc_message *rpc, int32_t flags); + +// Set the OP_DELETE selector field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_DELETE. +int32_t +mcd_rpc_op_delete_set_selector (mcd_rpc_message *rpc, const void *selector); + + +// Get the OP_KILL_CURSORS numberOfCursorIDs field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_KILL_CURSORS. +int32_t +mcd_rpc_op_kill_cursors_get_number_of_cursor_ids (const mcd_rpc_message *rpc); + +// Get the OP_KILL_CURSORS cursorIDs field. +// +// Returns `NULL` if the OP_KILL_CURSORS numberOfCursorIDs field equals 0. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_KILL_CURSORS. +const int64_t * +mcd_rpc_op_kill_cursors_get_cursor_ids (const mcd_rpc_message *rpc); + +// Set the OP_KILL_CURSORS cursorIDs field. +// +// The msgHeader.opCode field MUST equal MONGOC_OP_CODE_KILL_CURSORS. +int32_t +mcd_rpc_op_kill_cursors_set_cursor_ids (mcd_rpc_message *rpc, + const int64_t *cursor_ids, + int32_t number_of_cursor_ids); + + +#ifdef __cplusplus +} +#endif + +#endif // !defined(MCD_RPC_H_INCLUDED) diff --git a/src/mongoc/mcd-time.h b/src/mongoc/mcd-time.h new file mode 100644 index 00000000..4a1e3f9f --- /dev/null +++ b/src/mongoc/mcd-time.h @@ -0,0 +1,349 @@ +/** + * Copyright 2022 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MCD_TIME_H_INCLUDED +#define MCD_TIME_H_INCLUDED + +#include "mongoc-prelude.h" + +#include "./mcd-integer.h" + +#include + + +/** + * @brief Represents an abstract point-in-time. + * + * @note This is an *abstract* time point, with the only guarantee that it + * is strictly ordered with every other time point and that the difference + * between any two times will roughly encode actual wall-clock durations. + */ +typedef struct mcd_time_point { + /// The internal representation of the time. + int64_t _rep; +} mcd_time_point; + +/// The latest representable future point-in-time +#define MCD_TIME_POINT_MAX ((mcd_time_point){._rep = INT64_MAX}) +/// The oldest representable past point-in-time +#define MCD_TIME_POINT_MIN ((mcd_time_point){._rep = INT64_MIN}) + +/** + * @brief Represents a (possibly negative) duration of time. + * + * Construct this using one of the duration constructor functions. + * + * @note This encodes real wall-time durations, and may include negative + * durations. It can be compared with other durations and used to offset + * time points. + */ +typedef struct mcd_duration { + /// An internal representation of the duration + int64_t _rep; +} mcd_duration; + +/// The maximum representable duration +#define MCD_DURATION_MAX ((mcd_duration){._rep = INT64_MAX}) +/// The minimal representable (negative) duration +#define MCD_DURATION_MIN ((mcd_duration){._rep = INT64_MIN}) +/// A duration representing zero amount of time +#define MCD_DURATION_ZERO ((mcd_duration){._rep = 0}) + +/** + * @brief Obtain the current time point. This is only an abstract + * monotonically increasing time, and does not necessarily correlate with + * any real-world clock. + */ +static BSON_INLINE mcd_time_point +mcd_now (void) +{ + // Create a time point representing the current time. + return (mcd_time_point){._rep = bson_get_monotonic_time ()}; +} + +/** + * @brief Create a duration from a number of microseconds. + * + * @param s A number of microseconds + * @return mcd_duration A duration corresponding to 's' microseconds. + * + * @note Saturates to the min/max duration if the duration is too great in + * magnitude. + */ +static BSON_INLINE mcd_duration +mcd_microseconds (int64_t s) +{ + // 'mcd_duration' is encoded in a number of microseconds, so we don't need to + // do bounds checking here. + return (mcd_duration){._rep = s}; +} + +/** + * @brief Create a duration from a number of milliseconds. + * + * @param s A number of milliseconds + * @return mcd_duration A duration corresponding to 's' milliseconds. + * + * @note Saturates to the min/max duration if the duration is too great in + * magnitude. + */ +static BSON_INLINE mcd_duration +mcd_milliseconds (int64_t s) +{ + // 1'000 microseconds per millisecond: + if (_mcd_i64_mul_would_overflow (s, 1000)) { + return s < 0 ? MCD_DURATION_MIN : MCD_DURATION_MAX; + } + return mcd_microseconds (s * 1000); +} + +/** + * @brief Create a duration from a number of seconds. + * + * @param s A number of seconds + * @return mcd_duration A duration corresponding to 's' seconds. + * + * @note Saturates to the min/max duration if the duration is too great in + * magnitude. + */ +static BSON_INLINE mcd_duration +mcd_seconds (int64_t s) +{ + // 1'000 milliseconds per second: + if (_mcd_i64_mul_would_overflow (s, 1000)) { + return s < 0 ? MCD_DURATION_MIN : MCD_DURATION_MAX; + } + return mcd_milliseconds (s * 1000); +} + +/** + * @brief Create a duration from a number of minutes. + * + * @param m A number of minutes + * @return mcd_duration A duration corresponding to 's' minutes. + * + * @note Saturates to the min/max duration if the duration is too great in + * magnitude. + */ +static BSON_INLINE mcd_duration +mcd_minutes (int64_t m) +{ + // Sixty seconds per minute: + if (_mcd_i64_mul_would_overflow (m, 60)) { + return m < 0 ? MCD_DURATION_MIN : MCD_DURATION_MAX; + } + return mcd_seconds (m * 60); +} + +/** + * @brief Obtain the count of full milliseconds encoded in the given duration + * + * @param d An abstract duration + * @return int64_t The number of milliseconds in 'd' + * + * @note Does not round-trip with `mcd_milliseconds(N)` if N-milliseconds is + * unrepresentable in the duration type. This only occurs in extreme durations + */ +static BSON_INLINE int64_t +mcd_get_milliseconds (mcd_duration d) +{ + return d._rep / 1000; +} + +/** + * @brief Obtain a point-in-time relative to a base time offset by the given + * duration (which may be negative). + * + * @param from The basis of the time offset + * @param delta The amount of time to shift the resulting time point + * @return mcd_time_point If 'delta' is a positive duration, the result is a + * point-in-time *after* 'from'. If 'delta' is a negative duration, the result + * is a point-in-time *before* 'from'. + * + * @note If the resulting point-in-time is unrepresentable, the return value + * will be clamped to MCD_TIME_POINT_MIN or MCD_TIME_POINT_MAX. + */ +static BSON_INLINE mcd_time_point +mcd_later (mcd_time_point from, mcd_duration delta) +{ + if (_mcd_i64_add_would_overflow (from._rep, delta._rep)) { + return delta._rep < 0 ? MCD_TIME_POINT_MIN : MCD_TIME_POINT_MAX; + } else { + from._rep += delta._rep; + return from; + } +} + +/** + * @brief Obtain the duration between two points in time. + * + * @param then The target time + * @param from The base time + * @return mcd_duration The amount of time you would need to wait starting + * at 'from' for the time to become 'then' (the result may be a negative + * duration). + * + * Intuition: If "then" is "in the future" relative to "from", you will + * receive a positive duration, indicating an amount of time to wait + * beginning at 'from' to reach 'then'. If "then" is actually *before* + * "from", you will receive a paradoxical *negative* duration, indicating + * the amount of time needed to time-travel backwards to reach "then." + */ +static BSON_INLINE mcd_duration +mcd_time_difference (mcd_time_point then, mcd_time_point from) +{ + if (_mcd_i64_sub_would_overflow (then._rep, from._rep)) { + if (from._rep < 0) { + // Would overflow past the max + return MCD_DURATION_MAX; + } else { + // Would overflow past the min + return MCD_DURATION_MIN; + } + } else { + int64_t diff = then._rep - from._rep; + // Our time_point encodes the time using a microsecond counter. + return mcd_microseconds (diff); + } +} + +/** + * @brief Compare two time points to create an ordering. + * + * A time point "in the past" is "less than" a time point "in the future". + * + * @retval <0 If 'left' is before 'right' + * @retval >0 If 'right' is before 'left' + * @retval 0 If 'left' and 'right' are equivalent + */ +static BSON_INLINE int +mcd_time_compare (mcd_time_point left, mcd_time_point right) +{ + // Obtain the amount of time needed to wait from 'right' to reach + // 'left' + int64_t diff = mcd_time_difference (left, right)._rep; + if (diff < 0) { + // A negative duration indicates that 'left' is "before" 'right' + return -1; + } else if (diff > 0) { + // A positive duration indicates that 'left' is "after" 'right' + return 1; + } else { + // These time points are equivalent + return 0; + } +} + +/** + * @brief Compare two durations + * + * A duration D1 is "less than" a duration D2 if time-travelling/waiting for D1 + * duration would end in the past relative to time-travelling/waiting for D2. + * + * @retval <0 If left is "less than" right + * @retval >0 If left is "greater than" right + * @retval 0 If left and right are equivalent + */ +static BSON_INLINE int +mcd_duration_compare (mcd_duration left, mcd_duration right) +{ + if (left._rep < right._rep) { + return -1; + } else if (left._rep > right._rep) { + return 1; + } else { + return 0; + } +} + +/** + * @brief Clamp a duration between two other durations + * + * @param dur The duration to transform + * @param min The minimum duration + * @param max The maximum duration + * @retval min If `dur` < `min` + * @retval max If `dur` > `max` + * @retval dur Otherwise + */ +static BSON_INLINE mcd_duration +mcd_duration_clamp (mcd_duration dur, mcd_duration min, mcd_duration max) +{ + BSON_ASSERT (mcd_duration_compare (min, max) <= 0 && + "Invalid min-max range given to mcd_duration_clamp()"); + if (mcd_duration_compare (dur, min) < 0) { + // The duration is less than the minimum + return min; + } else if (mcd_duration_compare (dur, max) > 0) { + // The duration is greater than the maximum + return max; + } else { + // The duration is in-bounds + return dur; + } +} + +/// Represents a timer that can be expired +typedef struct mcd_timer { + /// The point in time after which the time will become expired. + mcd_time_point expire_at; +} mcd_timer; + +/// Create a time that will expire at the given time +static BSON_INLINE mcd_timer +mcd_timer_expire_at (mcd_time_point time) +{ + return (mcd_timer){time}; +} + +/** + * @brief Create a timer that will expire after waiting for the given duration + * relative to now + * + * @note If the duration is less-than or equal-to zero, the timer will already + * have expired + */ +static BSON_INLINE mcd_timer +mcd_timer_expire_after (mcd_duration after) +{ + return mcd_timer_expire_at (mcd_later (mcd_now (), after)); +} + +/** + * @brief Obtain the amount of time that one will need to WAIT before the timer + * will be an expired state. + * + * @return mcd_duration A non-negative duration. + * + * @note If the timer is already expired, returns a zero duration. Will never + * return a negative duration. + */ +static BSON_INLINE mcd_duration +mcd_timer_remaining (mcd_timer timer) +{ + // Compute the distance until the expiry time relative to now + mcd_duration remain = mcd_time_difference (timer.expire_at, mcd_now ()); + // Compare that duration with a zero duration + if (mcd_duration_compare (remain, mcd_microseconds (0)) < 0) { + // The "remaining" time is less-than zero, which means the timer is + // already expired, so we only need to wait for zero time: + return mcd_microseconds (0); + } + // There is a positive amount of time remaining + return remain; +} + +#endif // MCD_TIME_H_INCLUDED diff --git a/src/mongoc/mongoc-aggregate.c b/src/mongoc/mongoc-aggregate.c index 376ea2bc..83b4b4f1 100644 --- a/src/mongoc/mongoc-aggregate.c +++ b/src/mongoc/mongoc-aggregate.c @@ -23,6 +23,7 @@ #include "mongoc-trace-private.h" #include "mongoc-util-private.h" +#include /*-------------------------------------------------------------------------- * @@ -92,53 +93,81 @@ _make_agg_cmd (const char *ns, bson_t *command, bson_error_t *err) { - const char *dot; - bson_iter_t iter; - bson_t child; - bool has_write_key; - bson_iter_t has_write_key_iter; - - bson_init (command); - - dot = strstr (ns, "."); - - if (dot) { - /* Note: we're not validating that the collection name's length is one or - * more characters, as functions such as mongoc_client_get_collection also - * do not validate. */ - BSON_APPEND_UTF8 (command, "aggregate", dot + 1); - } else { - BSON_APPEND_INT32 (command, "aggregate", 1); + const char *const dot = strstr (ns, "."); + const char *error = NULL; + const char *error_hint = NULL; + + bsonBuild ( + *command, + kv ("aggregate", + if (dot, + /* Note: we're not validating that the collection name's length is + one or more characters, as functions such as + mongoc_client_get_collection also do not validate. */ + // If 'ns' contains a dot, insert the string after the dot: + then (cstr (dot + 1)), + // Otherwise just an integer 1: + else(int32 (1))))); + if ((error_hint = "append-aggregate", error = bsonBuildError)) { + goto fail; } /* * The following will allow @pipeline to be either an array of * items for the pipeline, or {"pipeline": [...]}. */ - if (bson_iter_init_find (&iter, pipeline, "pipeline") && - BSON_ITER_HOLDS_ARRAY (&iter)) { - bson_iter_recurse (&iter, &has_write_key_iter); - if (!bson_append_iter (command, "pipeline", 8, &iter)) { - bson_set_error (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Failed to append \"pipeline\" to create command."); - return false; - } - } else { - BSON_APPEND_ARRAY (command, "pipeline", pipeline); - bson_iter_init (&has_write_key_iter, pipeline); + bsonParse ( + *pipeline, + find (keyWithType ("pipeline", array), + // There is a "pipeline" array in the document + append (*command, kv ("pipeline", iterValue (bsonVisitIter)))), + else( // We did not find a "pipeline" array. copy the pipeline as + // an array into the command + append (*command, kv ("pipeline", array (insert (*pipeline, true)))))); + if ((error_hint = "append-pipeline", error = bsonParseError)) { + goto fail; } - has_write_key = _has_write_key (&has_write_key_iter); - bson_append_document_begin (command, "cursor", 6, &child); - /* Ignore batchSize=0 for aggregates with $out or $merge */ - if (opts->batchSize_is_set && !(has_write_key && opts->batchSize == 0)) { - BSON_APPEND_INT32 (&child, "batchSize", opts->batchSize); + // Check if there is a $merge or $out in the pipeline for the command + bool has_write_key = false; + bsonParse (*command, + find ( + // Find the "pipeline" array + keyWithType ("pipeline", array), + parse ( + // Find the last element of the pipeline array + find (lastElement, + // If it has an "$out" or "$merge" key, it is a + // writing aggregate command. + parse (find (key ("$out", "$merge"), + do(has_write_key = true))))))); + if ((error_hint = "parse-pipeline", error = bsonParseError)) { + goto fail; + } + + bsonBuildAppend ( + *command, + kv ("cursor", + // If batchSize is set, and if we are not a writing command with zero + // batchSize, append 'batchSize' to the cursor, otherwise leave the + // 'cursor' as an empty subdocument. + doc (if (opts->batchSize_is_set && + !(has_write_key && opts->batchSize == 0), + then (kv ("batchSize", int32 (opts->batchSize))))))); + if ((error_hint = "build-cursor", error = bsonBuildError)) { + goto fail; } - bson_append_document_end (command, &child); return true; + +fail: + bson_set_error (err, + MONGOC_ERROR_COMMAND, + MONGOC_ERROR_COMMAND_INVALID_ARG, + "Error while building aggregate command [%s]: %s", + error_hint, + error); + return false; } @@ -155,7 +184,7 @@ _make_agg_cmd (const char *ns, * The cursor may fail once iterated upon, so check * mongoc_cursor_error() if mongoc_cursor_next() returns false. * - * See http://docs.mongodb.org/manual/aggregation/ for more + * See https://www.mongodb.com/docs/manual/aggregation/ for more * information on how to build aggregation pipelines. * * Parameters: @@ -199,7 +228,7 @@ _mongoc_aggregate (mongoc_client_t *client, bson_iter_t ar; mongoc_cursor_t *cursor; bson_iter_t iter; - bson_t command; + bson_t command = BSON_INITIALIZER; bson_t cursor_opts; bool created_command; bson_error_t create_cmd_err = {0}; @@ -237,9 +266,7 @@ _mongoc_aggregate (mongoc_client_t *client, default_rp, default_rc); - if (created_command) { - bson_destroy (&command); - } + bson_destroy (&command); bson_destroy (&cursor_opts); if (!parsed_opts) { @@ -286,20 +313,6 @@ _mongoc_aggregate (mongoc_client_t *client, GOTO (done); } - if (aggregate_opts.write_concern_owned && has_write_key && - server_stream->sd->max_wire_version < WIRE_VERSION_CMD_WRITE_CONCERN) { - bson_set_error ( - &cursor->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "\"aggregate\" with \"$out\" or \"$merge\" does not support " - "writeConcern with wire version %d, wire version %d is " - "required", - server_stream->sd->max_wire_version, - WIRE_VERSION_CMD_WRITE_CONCERN); - GOTO (done); - } - /* Only inherit WriteConcern when aggregate has $out or $merge */ if (!aggregate_opts.write_concern_owned && has_write_key) { mongoc_write_concern_destroy (cursor->write_concern); diff --git a/src/mongoc/mongoc-apm.c b/src/mongoc/mongoc-apm.c index fda840fc..ddde6805 100644 --- a/src/mongoc/mongoc-apm.c +++ b/src/mongoc/mongoc-apm.c @@ -23,9 +23,9 @@ static bson_oid_t kObjectIdZero = {{0}}; /* * An Application Performance Management (APM) implementation, complying with - * MongoDB's Command Monitoring Spec: + * MongoDB's Command Logging and Monitoring Spec: * - * https://github.com/mongodb/specifications/tree/master/source/command-monitoring + * https://github.com/mongodb/specifications/tree/master/source/command-logging-and-monitoring */ static void @@ -392,6 +392,11 @@ mongoc_apm_command_started_get_server_connection_id ( { if (event->server_connection_id > INT32_MAX || event->server_connection_id < INT32_MIN) { + MONGOC_WARNING ( + "Server connection ID %" PRId64 + " is outside of int32 range. Returning -1. Use " + "mongoc_apm_command_started_get_server_connection_id_int64.", + event->server_connection_id); return MONGOC_NO_SERVER_CONNECTION_ID; } @@ -399,6 +404,14 @@ mongoc_apm_command_started_get_server_connection_id ( } +int64_t +mongoc_apm_command_started_get_server_connection_id_int64 ( + const mongoc_apm_command_started_t *event) +{ + return event->server_connection_id; +} + + void * mongoc_apm_command_started_get_context ( const mongoc_apm_command_started_t *event) @@ -484,6 +497,11 @@ mongoc_apm_command_succeeded_get_server_connection_id ( { if (event->server_connection_id > INT32_MAX || event->server_connection_id < INT32_MIN) { + MONGOC_WARNING ( + "Server connection ID %" PRId64 + " is outside of int32 range. Returning -1. Use " + "mongoc_apm_command_succeeded_get_server_connection_id_int64.", + event->server_connection_id); return MONGOC_NO_SERVER_CONNECTION_ID; } @@ -491,6 +509,14 @@ mongoc_apm_command_succeeded_get_server_connection_id ( } +int64_t +mongoc_apm_command_succeeded_get_server_connection_id_int64 ( + const mongoc_apm_command_succeeded_t *event) +{ + return event->server_connection_id; +} + + void * mongoc_apm_command_succeeded_get_context ( const mongoc_apm_command_succeeded_t *event) @@ -580,6 +606,11 @@ mongoc_apm_command_failed_get_server_connection_id ( { if (event->server_connection_id > INT32_MAX || event->server_connection_id < INT32_MIN) { + MONGOC_WARNING ( + "Server connection ID %" PRId64 + " is outside of int32 range. Returning -1. Use " + "mongoc_apm_command_failed_get_server_connection_id_int64.", + event->server_connection_id); return MONGOC_NO_SERVER_CONNECTION_ID; } @@ -587,6 +618,14 @@ mongoc_apm_command_failed_get_server_connection_id ( } +int64_t +mongoc_apm_command_failed_get_server_connection_id_int64 ( + const mongoc_apm_command_failed_t *event) +{ + return event->server_connection_id; +} + + void * mongoc_apm_command_failed_get_context (const mongoc_apm_command_failed_t *event) { diff --git a/src/mongoc/mongoc-apm.h b/src/mongoc/mongoc-apm.h index 7fe95d33..70e30448 100644 --- a/src/mongoc/mongoc-apm.h +++ b/src/mongoc/mongoc-apm.h @@ -30,9 +30,9 @@ BSON_BEGIN_DECLS /* * Application Performance Management (APM) interface, complies with two specs. - * MongoDB's Command Monitoring Spec: + * MongoDB's Command Logging and Monitoring Spec: * - * https://github.com/mongodb/specifications/tree/master/source/command-monitoring + * https://github.com/mongodb/specifications/tree/master/source/command-logging-and-monitoring * * MongoDB's Spec for Monitoring Server Discovery and Monitoring (SDAM) events: * @@ -104,6 +104,11 @@ mongoc_apm_command_started_get_service_id ( const mongoc_apm_command_started_t *event); MONGOC_EXPORT (int32_t) mongoc_apm_command_started_get_server_connection_id ( + const mongoc_apm_command_started_t *event) + BSON_GNUC_DEPRECATED_FOR ( + "mongoc_apm_command_started_get_server_connection_id_int64"); +MONGOC_EXPORT (int64_t) +mongoc_apm_command_started_get_server_connection_id_int64 ( const mongoc_apm_command_started_t *event); MONGOC_EXPORT (void *) mongoc_apm_command_started_get_context ( @@ -137,6 +142,11 @@ mongoc_apm_command_succeeded_get_service_id ( const mongoc_apm_command_succeeded_t *event); MONGOC_EXPORT (int32_t) mongoc_apm_command_succeeded_get_server_connection_id ( + const mongoc_apm_command_succeeded_t *event) + BSON_GNUC_DEPRECATED_FOR ( + "mongoc_apm_command_succeeded_get_server_connection_id_int64"); +MONGOC_EXPORT (int64_t) +mongoc_apm_command_succeeded_get_server_connection_id_int64 ( const mongoc_apm_command_succeeded_t *event); MONGOC_EXPORT (void *) mongoc_apm_command_succeeded_get_context ( @@ -172,6 +182,11 @@ mongoc_apm_command_failed_get_service_id ( const mongoc_apm_command_failed_t *event); MONGOC_EXPORT (int32_t) mongoc_apm_command_failed_get_server_connection_id ( + const mongoc_apm_command_failed_t *event) + BSON_GNUC_DEPRECATED_FOR ( + "mongoc_apm_command_failed_get_server_connection_id_int64"); +MONGOC_EXPORT (int64_t) +mongoc_apm_command_failed_get_server_connection_id_int64 ( const mongoc_apm_command_failed_t *event); MONGOC_EXPORT (void *) mongoc_apm_command_failed_get_context ( diff --git a/src/mongoc/mongoc-async-cmd-private.h b/src/mongoc/mongoc-async-cmd-private.h index 7d495b55..ccf58dfb 100644 --- a/src/mongoc/mongoc-async-cmd-private.h +++ b/src/mongoc/mongoc-async-cmd-private.h @@ -21,11 +21,12 @@ #include +#include "mcd-rpc.h" #include "mongoc-client.h" #include "mongoc-async-private.h" #include "mongoc-array-private.h" #include "mongoc-buffer-private.h" -#include "mongoc-rpc-private.h" +#include "mongoc-cmd-private.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS @@ -58,12 +59,11 @@ typedef struct _mongoc_async_cmd { int64_t timeout_msec; bson_t cmd; mongoc_buffer_t buffer; - mongoc_array_t array; mongoc_iovec_t *iovec; size_t niovec; size_t bytes_written; size_t bytes_to_read; - mongoc_rpc_t rpc; + mcd_rpc_message *rpc; bson_t reply; bool reply_needs_cleanup; char *ns; @@ -84,7 +84,7 @@ mongoc_async_cmd_new (mongoc_async_t *async, void *setup_ctx, const char *dbname, const bson_t *cmd, - const mongoc_opcode_t cmd_opcode, + const int32_t cmd_opcode, mongoc_async_cmd_cb_t cb, void *cb_data, int64_t timeout_msec); diff --git a/src/mongoc/mongoc-async-cmd.c b/src/mongoc/mongoc-async-cmd.c index 0d292bea..3ba89961 100644 --- a/src/mongoc/mongoc-async-cmd.c +++ b/src/mongoc/mongoc-async-cmd.c @@ -20,6 +20,7 @@ #include "mongoc-client.h" #include "mongoc-async-cmd-private.h" #include "mongoc-async-private.h" +#include "mongoc-cluster-private.h" #include "mongoc-error.h" #include "mongoc-opcode.h" #include "mongoc-rpc-private.h" @@ -133,42 +134,47 @@ mongoc_async_cmd_run (mongoc_async_cmd_t *acmd) return false; } -void -_mongoc_async_cmd_init_send (const mongoc_opcode_t cmd_opcode, +static void +_mongoc_async_cmd_init_send (const int32_t cmd_opcode, mongoc_async_cmd_t *acmd, const char *dbname) { - acmd->rpc.header.msg_len = 0; - acmd->rpc.header.request_id = ++acmd->async->request_id; - acmd->rpc.header.response_to = 0; + BSON_ASSERT (cmd_opcode == MONGOC_OP_CODE_QUERY || + cmd_opcode == MONGOC_OP_CODE_MSG); - if (MONGOC_OPCODE_QUERY == cmd_opcode) { - acmd->ns = bson_strdup_printf ("%s.$cmd", dbname); - acmd->rpc.header.opcode = MONGOC_OPCODE_QUERY; - acmd->rpc.query.flags = MONGOC_QUERY_SECONDARY_OK; - acmd->rpc.query.collection = acmd->ns; - acmd->rpc.query.skip = 0; - acmd->rpc.query.n_return = -1; - acmd->rpc.query.query = bson_get_data (&acmd->cmd); - acmd->rpc.query.fields = NULL; - } + int32_t message_length = 0; - if (MONGOC_OPCODE_MSG == cmd_opcode) { - acmd->rpc.header.opcode = MONGOC_OPCODE_MSG; + message_length += mcd_rpc_header_set_message_length (acmd->rpc, 0); + message_length += + mcd_rpc_header_set_request_id (acmd->rpc, ++acmd->async->request_id); + message_length += mcd_rpc_header_set_response_to (acmd->rpc, 0); + message_length += mcd_rpc_header_set_op_code (acmd->rpc, cmd_opcode); - acmd->rpc.msg.msg_len = 0; - acmd->rpc.msg.flags = 0; - acmd->rpc.msg.n_sections = 1; - acmd->rpc.msg.sections[0].payload_type = 0; - acmd->rpc.msg.sections[0].payload.bson_document = - bson_get_data (&acmd->cmd); + if (cmd_opcode == MONGOC_OP_CODE_QUERY) { + acmd->ns = bson_strdup_printf ("%s.$cmd", dbname); + message_length += mcd_rpc_op_query_set_flags ( + acmd->rpc, MONGOC_OP_QUERY_FLAG_SECONDARY_OK); + message_length += + mcd_rpc_op_query_set_full_collection_name (acmd->rpc, acmd->ns); + message_length += mcd_rpc_op_query_set_number_to_skip (acmd->rpc, 0); + message_length += mcd_rpc_op_query_set_number_to_return (acmd->rpc, -1); + message_length += + mcd_rpc_op_query_set_query (acmd->rpc, bson_get_data (&acmd->cmd)); + } else { + mcd_rpc_op_msg_set_sections_count (acmd->rpc, 1u); + message_length += + mcd_rpc_op_msg_set_flag_bits (acmd->rpc, MONGOC_OP_MSG_FLAG_NONE); + message_length += mcd_rpc_op_msg_section_set_kind (acmd->rpc, 0u, 0); + message_length += mcd_rpc_op_msg_section_set_body ( + acmd->rpc, 0u, bson_get_data (&acmd->cmd)); } + mcd_rpc_message_set_length (acmd->rpc, message_length); + /* This will always be hello, which are not allowed to be compressed */ - _mongoc_rpc_gather (&acmd->rpc, &acmd->array); - acmd->iovec = (mongoc_iovec_t *) acmd->array.data; - acmd->niovec = acmd->array.len; - _mongoc_rpc_swab_to_le (&acmd->rpc); + acmd->iovec = mcd_rpc_message_to_iovecs (acmd->rpc, &acmd->niovec); + BSON_ASSERT (acmd->iovec); + acmd->bytes_written = 0; } @@ -197,17 +203,15 @@ mongoc_async_cmd_new (mongoc_async_t *async, void *setup_ctx, const char *dbname, const bson_t *cmd, - const mongoc_opcode_t cmd_opcode, /* OP_QUERY or OP_MSG */ + const int32_t cmd_opcode, /* OP_QUERY or OP_MSG */ mongoc_async_cmd_cb_t cb, void *cb_data, int64_t timeout_msec) { - mongoc_async_cmd_t *acmd; + BSON_ASSERT_PARAM (cmd); + BSON_ASSERT_PARAM (dbname); - BSON_ASSERT (cmd); - BSON_ASSERT (dbname); - - acmd = BSON_ALIGNED_ALLOC0 (mongoc_async_cmd_t); + mongoc_async_cmd_t *const acmd = BSON_ALIGNED_ALLOC0 (mongoc_async_cmd_t); acmd->async = async; acmd->dns_result = dns_result; acmd->timeout_msec = timeout_msec; @@ -221,12 +225,13 @@ mongoc_async_cmd_new (mongoc_async_t *async, acmd->connect_started = bson_get_monotonic_time (); bson_copy_to (cmd, &acmd->cmd); - if (MONGOC_OPCODE_MSG == cmd_opcode) { - /* If we're sending an OPCODE_MSG, we need to add the "db" field: */ + if (MONGOC_OP_CODE_MSG == cmd_opcode) { + /* If we're sending an OP_MSG, we need to add the "db" field: */ bson_append_utf8 (&acmd->cmd, "$db", 3, "admin", 5); } - _mongoc_array_init (&acmd->array, sizeof (mongoc_iovec_t)); + acmd->rpc = mcd_rpc_message_new (); + acmd->iovec = NULL; _mongoc_buffer_init (&acmd->buffer, NULL, 0, NULL, NULL); _mongoc_async_cmd_init_send (cmd_opcode, acmd, dbname); @@ -254,8 +259,9 @@ mongoc_async_cmd_destroy (mongoc_async_cmd_t *acmd) bson_destroy (&acmd->reply); } - _mongoc_array_destroy (&acmd->array); + bson_free (acmd->iovec); _mongoc_buffer_destroy (&acmd->buffer); + mcd_rpc_message_destroy (acmd->rpc); bson_free (acmd->ns); bson_free (acmd); @@ -311,13 +317,12 @@ _mongoc_async_cmd_phase_send (mongoc_async_cmd_t *acmd) size_t total_bytes = 0; size_t offset; ssize_t bytes; - int i; /* if a continued write, then iovec will be set to a temporary copy */ bool used_temp_iovec = false; mongoc_iovec_t *iovec = acmd->iovec; size_t niovec = acmd->niovec; - for (i = 0; i < acmd->niovec; i++) { + for (size_t i = 0u; i < acmd->niovec; i++) { total_bytes += acmd->iovec[i].iov_len; } @@ -327,8 +332,10 @@ _mongoc_async_cmd_phase_send (mongoc_async_cmd_t *acmd) * iovec entry to be written. */ offset = acmd->bytes_written; + size_t i = 0u; + /* subtract the lengths of all iovec entries written so far. */ - for (i = 0; i < acmd->niovec; i++) { + for (i = 0u; i < acmd->niovec; i++) { if (offset < acmd->iovec[i].iov_len) { break; } @@ -346,6 +353,7 @@ _mongoc_async_cmd_phase_send (mongoc_async_cmd_t *acmd) used_temp_iovec = true; } + mcd_rpc_message_egress (acmd->rpc); bytes = mongoc_stream_writev (acmd->stream, iovec, niovec, 0); if (used_temp_iovec) { @@ -459,38 +467,39 @@ _mongoc_async_cmd_phase_recv_rpc (mongoc_async_cmd_t *acmd) acmd->bytes_to_read = (size_t) (acmd->bytes_to_read - bytes); if (!acmd->bytes_to_read) { - if (!_mongoc_rpc_scatter ( - &acmd->rpc, acmd->buffer.data, acmd->buffer.len)) { + mcd_rpc_message_reset (acmd->rpc); + if (!mcd_rpc_message_from_data_in_place ( + acmd->rpc, acmd->buffer.data, acmd->buffer.len, NULL)) { bson_set_error (&acmd->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid reply from server."); return MONGOC_ASYNC_CMD_ERROR; } - if (BSON_UINT32_FROM_LE (acmd->rpc.header.opcode) == - MONGOC_OPCODE_COMPRESSED) { - uint8_t *buf = NULL; - size_t len = - BSON_UINT32_FROM_LE (acmd->rpc.compressed.uncompressed_size) + - sizeof (mongoc_rpc_header_t); - - buf = bson_malloc0 (len); - if (!_mongoc_rpc_decompress (&acmd->rpc, buf, len)) { - bson_free (buf); - bson_set_error (&acmd->error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Could not decompress server reply"); - return MONGOC_ASYNC_CMD_ERROR; - } + mcd_rpc_message_ingress (acmd->rpc); - _mongoc_buffer_destroy (&acmd->buffer); - _mongoc_buffer_init (&acmd->buffer, buf, len, NULL, NULL); + void *decompressed_data; + size_t decompressed_data_len; + + if (!mcd_rpc_message_decompress_if_necessary ( + acmd->rpc, &decompressed_data, &decompressed_data_len)) { + bson_set_error (&acmd->error, + MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "Could not decompress server reply"); + return MONGOC_ASYNC_CMD_ERROR; } - _mongoc_rpc_swab_from_le (&acmd->rpc); + if (decompressed_data) { + _mongoc_buffer_destroy (&acmd->buffer); + _mongoc_buffer_init (&acmd->buffer, + decompressed_data, + decompressed_data_len, + NULL, + NULL); + } - if (!_mongoc_rpc_get_first_document (&acmd->rpc, &acmd->reply)) { + if (!mcd_rpc_message_get_body (acmd->rpc, &acmd->reply)) { bson_set_error (&acmd->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, diff --git a/src/mongoc/mongoc-buffer-private.h b/src/mongoc/mongoc-buffer-private.h index 3c14d61e..36c71446 100644 --- a/src/mongoc/mongoc-buffer-private.h +++ b/src/mongoc/mongoc-buffer-private.h @@ -55,20 +55,20 @@ bool _mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t size, - int32_t timeout_msec, + int64_t timeout_msec, bson_error_t *error); ssize_t _mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t size, - int32_t timeout_msec); + int64_t timeout_msec); ssize_t _mongoc_buffer_fill (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t min_bytes, - int32_t timeout_msec, + int64_t timeout_msec, bson_error_t *error); void diff --git a/src/mongoc/mongoc-buffer.c b/src/mongoc/mongoc-buffer.c index 1952edbd..d8bd2892 100644 --- a/src/mongoc/mongoc-buffer.c +++ b/src/mongoc/mongoc-buffer.c @@ -31,8 +31,15 @@ #endif -#define SPACE_FOR(_b, _sz) \ - (((ssize_t) (_b)->datalen - (ssize_t) (_b)->len) >= (ssize_t) (_sz)) +static void +make_space_for (mongoc_buffer_t *buffer, size_t data_size) +{ + if (buffer->len + data_size > buffer->datalen) { + buffer->datalen = bson_next_power_of_two (buffer->len + data_size); + buffer->data = (uint8_t *) buffer->realloc_func ( + buffer->data, buffer->datalen, buffer->realloc_data); + } +} /** @@ -135,12 +142,7 @@ _mongoc_buffer_append (mongoc_buffer_t *buffer, BSON_ASSERT (buffer->datalen); - if (!SPACE_FOR (buffer, data_size)) { - BSON_ASSERT ((buffer->datalen + data_size) < INT_MAX); - buffer->datalen = bson_next_power_of_two (data_size + buffer->len); - buffer->data = - (uint8_t *) buffer->realloc_func (buffer->data, buffer->datalen, NULL); - } + make_space_for (buffer, data_size); buf = &buffer->data[buffer->len]; @@ -172,7 +174,7 @@ bool _mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t size, - int32_t timeout_msec, + int64_t timeout_msec, bson_error_t *error) { uint8_t *buf; @@ -186,29 +188,34 @@ _mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer, BSON_ASSERT (buffer->datalen); - if (!SPACE_FOR (buffer, size)) { - BSON_ASSERT ((buffer->datalen + size) < INT_MAX); - buffer->datalen = bson_next_power_of_two (size + buffer->len); - buffer->data = - (uint8_t *) buffer->realloc_func (buffer->data, buffer->datalen, NULL); - } + make_space_for (buffer, size); buf = &buffer->data[buffer->len]; BSON_ASSERT ((buffer->len + size) <= buffer->datalen); - ret = mongoc_stream_read (stream, buf, size, size, timeout_msec); - if (ret != size) { + if (BSON_UNLIKELY (!bson_in_range_signed (int32_t, timeout_msec))) { + // CDRIVER-4589 + bson_set_error (error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "timeout_msec value %" PRId64 + " exceeds supported 32-bit range", + timeout_msec); + RETURN (false); + } + + ret = mongoc_stream_read (stream, buf, size, size, (int32_t) timeout_msec); + if (bson_cmp_not_equal_su (ret, size)) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, - "Failed to read %" PRIu64 - " bytes: socket error or timeout", - (uint64_t) size); + "Failed to read %zu bytes: socket error or timeout", + size); RETURN (false); } - buffer->len += ret; + buffer->len += (size_t) ret; RETURN (true); } @@ -229,7 +236,7 @@ ssize_t _mongoc_buffer_fill (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t min_bytes, - int32_t timeout_msec, + int64_t timeout_msec, bson_error_t *error) { ssize_t ret; @@ -244,44 +251,56 @@ _mongoc_buffer_fill (mongoc_buffer_t *buffer, BSON_ASSERT (buffer->datalen); if (min_bytes <= buffer->len) { - RETURN (buffer->len); + BSON_ASSERT (bson_in_range_unsigned (ssize_t, buffer->len)); + RETURN ((ssize_t) buffer->len); } min_bytes -= buffer->len; - if (!SPACE_FOR (buffer, min_bytes)) { - buffer->datalen = bson_next_power_of_two (buffer->len + min_bytes); - buffer->data = (uint8_t *) buffer->realloc_func ( - buffer->data, buffer->datalen, buffer->realloc_data); - } + make_space_for (buffer, min_bytes); avail_bytes = buffer->datalen - buffer->len; - ret = mongoc_stream_read ( - stream, &buffer->data[buffer->len], avail_bytes, min_bytes, timeout_msec); + if (BSON_UNLIKELY (!bson_in_range_signed (int32_t, timeout_msec))) { + // CDRIVER-4589 + bson_set_error (error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "timeout_msec value %" PRId64 + " exceeds supported 32-bit range", + timeout_msec); + RETURN (false); + } + + ret = mongoc_stream_read (stream, + &buffer->data[buffer->len], + avail_bytes, + min_bytes, + (int32_t) timeout_msec); - if (ret == -1) { + if (ret < 0) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, - "Failed to buffer %u bytes", - (unsigned) min_bytes); + "Failed to buffer %zu bytes", + min_bytes); RETURN (-1); } - buffer->len += ret; + buffer->len += (size_t) ret; if (buffer->len < min_bytes) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, - "Could only buffer %u of %u bytes", - (unsigned) buffer->len, - (unsigned) min_bytes); + "Could only buffer %zu of %zu bytes", + buffer->len, + min_bytes); RETURN (-1); } - RETURN (buffer->len); + BSON_ASSERT (bson_in_range_unsigned (ssize_t, buffer->len)); + RETURN ((ssize_t) buffer->len); } @@ -302,7 +321,7 @@ ssize_t _mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t size, - int32_t timeout_msec) + int64_t timeout_msec) { uint8_t *buf; ssize_t ret; @@ -315,21 +334,24 @@ _mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer, BSON_ASSERT (buffer->datalen); - if (!SPACE_FOR (buffer, size)) { - BSON_ASSERT ((buffer->datalen + size) < INT_MAX); - buffer->datalen = bson_next_power_of_two (size + buffer->len); - buffer->data = - (uint8_t *) buffer->realloc_func (buffer->data, buffer->datalen, NULL); - } + make_space_for (buffer, size); buf = &buffer->data[buffer->len]; BSON_ASSERT ((buffer->len + size) <= buffer->datalen); - ret = mongoc_stream_read (stream, buf, size, 0, timeout_msec); + if (BSON_UNLIKELY (!bson_in_range_signed (int32_t, timeout_msec))) { + // CDRIVER-4589 + MONGOC_ERROR ("timeout_msec value %" PRId64 + " exceeds supported 32-bit range", + timeout_msec); + RETURN (-1); + } + + ret = mongoc_stream_read (stream, buf, size, 0, (int32_t) timeout_msec); if (ret > 0) { - buffer->len += ret; + buffer->len += (size_t) ret; } RETURN (ret); diff --git a/src/mongoc/mongoc-bulk-operation.c b/src/mongoc/mongoc-bulk-operation.c index 3578a29c..d5a4a67e 100644 --- a/src/mongoc/mongoc-bulk-operation.c +++ b/src/mongoc/mongoc-bulk-operation.c @@ -93,10 +93,9 @@ void mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk) /* IN */ { mongoc_write_command_t *command; - int i; if (bulk) { - for (i = 0; i < bulk->commands.len; i++) { + for (size_t i = 0; i < bulk->commands.len; i++) { command = &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, i); _mongoc_write_command_destroy (command); @@ -750,7 +749,6 @@ mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, /* IN */ mongoc_server_stream_t *server_stream; bool ret; uint32_t offset = 0; - int i; ENTRY; @@ -807,7 +805,7 @@ mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, /* IN */ GOTO (err); } - for (i = 0; i < bulk->commands.len; i++) { + for (size_t i = 0u; i < bulk->commands.len; i++) { if (bulk->server_id) { server_stream = mongoc_cluster_stream_for_server (cluster, @@ -818,7 +816,7 @@ mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, /* IN */ error); } else { server_stream = mongoc_cluster_stream_for_writes ( - cluster, bulk->session, reply, error); + cluster, bulk->session, NULL, reply, error); } if (!server_stream) { diff --git a/src/mongoc/mongoc-change-stream-private.h b/src/mongoc/mongoc-change-stream-private.h index c0f774a3..a38e5ba6 100644 --- a/src/mongoc/mongoc-change-stream-private.h +++ b/src/mongoc/mongoc-change-stream-private.h @@ -39,6 +39,7 @@ struct _mongoc_change_stream_t { bson_t resume_token; bson_t *full_document; bson_t *full_document_before_change; + bool show_expanded_events; bson_error_t err; bson_t err_doc; diff --git a/src/mongoc/mongoc-change-stream.c b/src/mongoc/mongoc-change-stream.c index ba817e61..15c568c7 100644 --- a/src/mongoc/mongoc-change-stream.c +++ b/src/mongoc/mongoc-change-stream.c @@ -107,7 +107,7 @@ _make_command (mongoc_change_stream_t *stream, bson_t *command) bson_iter_t iter; bson_t change_stream_stage; /* { $changeStream: } */ bson_t change_stream_doc; - bson_t pipeline; + bson_array_builder_t *pipeline; bson_t cursor_doc; if (stream->change_stream_type == MONGOC_CHANGE_STREAM_COLLECTION) { @@ -117,10 +117,10 @@ _make_command (mongoc_change_stream_t *stream, bson_t *command) bson_append_int32 (command, "aggregate", 9, 1); } - bson_append_array_begin (command, "pipeline", 8, &pipeline); + bson_append_array_builder_begin (command, "pipeline", 8, &pipeline); /* append the $changeStream stage. */ - bson_append_document_begin (&pipeline, "0", 1, &change_stream_stage); + bson_array_builder_append_document_begin (pipeline, &change_stream_stage); bson_append_document_begin ( &change_stream_stage, "$changeStream", 13, &change_stream_doc); if (stream->full_document) { @@ -129,6 +129,11 @@ _make_command (mongoc_change_stream_t *stream, bson_t *command) if (stream->full_document_before_change) { bson_concat (&change_stream_doc, stream->full_document_before_change); } + if (stream->show_expanded_events) { + BSON_APPEND_BOOL (&change_stream_doc, + "showExpandedEvents", + stream->show_expanded_events); + } if (stream->resumed) { /* Change stream spec: Resume Process */ @@ -187,29 +192,23 @@ _make_command (mongoc_change_stream_t *stream, bson_t *command) bson_append_bool (&change_stream_doc, "allChangesForCluster", 20, true); } bson_append_document_end (&change_stream_stage, &change_stream_doc); - bson_append_document_end (&pipeline, &change_stream_stage); + bson_array_builder_append_document_end (pipeline, &change_stream_stage); /* Append user pipeline if it exists */ if (bson_iter_init_find (&iter, &stream->pipeline_to_append, "pipeline") && BSON_ITER_HOLDS_ARRAY (&iter)) { bson_iter_t child_iter; - uint32_t key_int = 1; - char buf[16]; - const char *key_str; BSON_ASSERT (bson_iter_recurse (&iter, &child_iter)); while (bson_iter_next (&child_iter)) { /* the user pipeline may consist of invalid stages or non-documents. * append anyway, and rely on the server error. */ - size_t keyLen = - bson_uint32_to_string (key_int, &key_str, buf, sizeof (buf)); - bson_append_value ( - &pipeline, key_str, (int) keyLen, bson_iter_value (&child_iter)); - ++key_int; + bson_array_builder_append_value (pipeline, + bson_iter_value (&child_iter)); } } - bson_append_array_end (command, &pipeline); + bson_append_array_builder_end (command, pipeline); /* Add batch size if needed */ bson_append_document_begin (command, "cursor", 6, &cursor_doc); @@ -289,13 +288,12 @@ _make_cursor (mongoc_change_stream_t *stream) goto cleanup; } - server_stream = - mongoc_cluster_stream_for_reads (&stream->client->cluster, - stream->read_prefs, - cs, - &reply, - /* Not aggregate-with-write */ false, - &stream->err); + server_stream = mongoc_cluster_stream_for_reads (&stream->client->cluster, + stream->read_prefs, + cs, + NULL, + &reply, + &stream->err); if (!server_stream) { bson_destroy (&stream->err_doc); bson_copy_to (&reply, &stream->err_doc); @@ -433,6 +431,7 @@ _change_stream_init (mongoc_change_stream_t *stream, stream->batch_size = stream->opts.batchSize; stream->max_await_time_ms = stream->opts.maxAwaitTimeMS; + stream->show_expanded_events = stream->opts.showExpandedEvents; /* Accept two forms of user pipeline: * 1. A document like: { "pipeline": [...] } diff --git a/src/mongoc/mongoc-client-pool.c b/src/mongoc/mongoc-client-pool.c index 987938a6..486b5c5c 100644 --- a/src/mongoc/mongoc-client-pool.c +++ b/src/mongoc/mongoc-client-pool.c @@ -60,6 +60,8 @@ void mongoc_client_pool_set_ssl_opts (mongoc_client_pool_t *pool, const mongoc_ssl_opt_t *opts) { + BSON_ASSERT_PARAM (pool); + bson_mutex_lock (&pool->mutex); _mongoc_ssl_opts_cleanup (&pool->ssl_opts, @@ -83,6 +85,8 @@ void _mongoc_client_pool_set_internal_tls_opts ( mongoc_client_pool_t *pool, _mongoc_internal_tls_opts_t *internal) { + BSON_ASSERT_PARAM (pool); + bson_mutex_lock (&pool->mutex); if (!pool->ssl_opts_set) { bson_mutex_unlock (&pool->mutex); @@ -252,6 +256,8 @@ mongoc_client_pool_destroy (mongoc_client_pool_t *pool) static void _start_scanner_if_needed (mongoc_client_pool_t *pool) { + BSON_ASSERT_PARAM (pool); + if (!pool->topology->single_threaded) { _mongoc_topology_background_monitoring_start (pool->topology); } @@ -260,6 +266,9 @@ _start_scanner_if_needed (mongoc_client_pool_t *pool) static void _initialize_new_client (mongoc_client_pool_t *pool, mongoc_client_t *client) { + BSON_ASSERT_PARAM (pool); + BSON_ASSERT_PARAM (client); + /* for tests */ mongoc_client_set_stream_initiator ( client, @@ -292,7 +301,7 @@ mongoc_client_pool_pop (mongoc_client_pool_t *pool) ENTRY; - BSON_ASSERT (pool); + BSON_ASSERT_PARAM (pool); wait_queue_timeout_ms = mongoc_uri_get_option_as_int32 ( pool->uri, MONGOC_URI_WAITQUEUETIMEOUTMS, -1); @@ -343,7 +352,7 @@ mongoc_client_pool_try_pop (mongoc_client_pool_t *pool) ENTRY; - BSON_ASSERT (pool); + BSON_ASSERT_PARAM (pool); bson_mutex_lock (&pool->mutex); @@ -370,8 +379,8 @@ mongoc_client_pool_push (mongoc_client_pool_t *pool, mongoc_client_t *client) { ENTRY; - BSON_ASSERT (pool); - BSON_ASSERT (client); + BSON_ASSERT_PARAM (pool); + BSON_ASSERT_PARAM (client); bson_mutex_lock (&pool->mutex); _mongoc_queue_push_head (&pool->queue, client); @@ -398,6 +407,8 @@ _mongoc_client_pool_set_stream_initiator (mongoc_client_pool_t *pool, mongoc_stream_initiator_t si, void *context) { + BSON_ASSERT_PARAM (pool); + mongoc_topology_scanner_set_stream_initiator ( pool->topology->scanner, si, context); } @@ -409,6 +420,7 @@ mongoc_client_pool_get_size (mongoc_client_pool_t *pool) size_t size = 0; ENTRY; + BSON_ASSERT_PARAM (pool); bson_mutex_lock (&pool->mutex); size = pool->size; @@ -424,6 +436,7 @@ mongoc_client_pool_num_pushed (mongoc_client_pool_t *pool) size_t num_pushed = 0; ENTRY; + BSON_ASSERT_PARAM (pool); bson_mutex_lock (&pool->mutex); num_pushed = pool->queue.length; @@ -436,6 +449,8 @@ mongoc_client_pool_num_pushed (mongoc_client_pool_t *pool) mongoc_topology_t * _mongoc_client_pool_get_topology (mongoc_client_pool_t *pool) { + BSON_ASSERT_PARAM (pool); + return pool->topology; } @@ -444,6 +459,7 @@ void mongoc_client_pool_max_size (mongoc_client_pool_t *pool, uint32_t max_pool_size) { ENTRY; + BSON_ASSERT_PARAM (pool); bson_mutex_lock (&pool->mutex); pool->max_pool_size = max_pool_size; @@ -456,6 +472,7 @@ void mongoc_client_pool_min_size (mongoc_client_pool_t *pool, uint32_t min_pool_size) { ENTRY; + BSON_ASSERT_PARAM (pool); MONGOC_WARNING ( "mongoc_client_pool_min_size is deprecated; its behavior does not match" @@ -473,6 +490,8 @@ mongoc_client_pool_set_apm_callbacks (mongoc_client_pool_t *pool, mongoc_apm_callbacks_t *callbacks, void *context) { + BSON_ASSERT_PARAM (pool); + mongoc_topology_t *const topology = BSON_ASSERT_PTR_INLINE (pool)->topology; mc_tpld_modification tdmod; @@ -510,6 +529,8 @@ mongoc_client_pool_set_error_api (mongoc_client_pool_t *pool, int32_t version) return false; } + BSON_ASSERT_PARAM (pool); + if (pool->error_api_set) { MONGOC_ERROR ("Can only set Error API Version once"); return false; @@ -526,6 +547,8 @@ mongoc_client_pool_set_appname (mongoc_client_pool_t *pool, const char *appname) { bool ret; + BSON_ASSERT_PARAM (pool); + bson_mutex_lock (&pool->mutex); ret = _mongoc_topology_set_appname (pool->topology, appname); bson_mutex_unlock (&pool->mutex); @@ -538,6 +561,8 @@ mongoc_client_pool_enable_auto_encryption (mongoc_client_pool_t *pool, mongoc_auto_encryption_opts_t *opts, bson_error_t *error) { + BSON_ASSERT_PARAM (pool); + return _mongoc_cse_client_pool_enable_auto_encryption ( pool->topology, opts, error); } diff --git a/src/mongoc/mongoc-client-private.h b/src/mongoc/mongoc-client-private.h index 56aaaf7c..7a90dbe6 100644 --- a/src/mongoc/mongoc-client-private.h +++ b/src/mongoc/mongoc-client-private.h @@ -41,36 +41,8 @@ BSON_BEGIN_DECLS -/* Range of wire protocol versions this driver supports. Bumping - * WIRE_VERSION_MAX must be accompanied by an update to - * `_mongoc_wire_version_to_server_version`. */ -#define WIRE_VERSION_MIN 6 /* a.k.a. minWireVersion */ -#define WIRE_VERSION_MAX 17 /* a.k.a. maxWireVersion */ - -/* first version that supported "find" and "getMore" commands */ -#define WIRE_VERSION_FIND_CMD 4 -/* first version with "killCursors" command */ -#define WIRE_VERSION_KILLCURSORS_CMD 4 -/* first version when findAndModify accepts writeConcern */ -#define WIRE_VERSION_FAM_WRITE_CONCERN 4 -/* first version to support readConcern */ -#define WIRE_VERSION_READ_CONCERN 4 -/* first version to support maxStalenessSeconds */ -#define WIRE_VERSION_MAX_STALENESS 5 -/* first version to support writeConcern */ -#define WIRE_VERSION_CMD_WRITE_CONCERN 5 -/* first version to support collation */ -#define WIRE_VERSION_COLLATION 5 -/* first version to support server-side errors for unsupported hint options */ -#define WIRE_VERSION_HINT_SERVER_SIDE_ERROR 5 -/* first version to support OP_MSG */ -#define WIRE_VERSION_OP_MSG 6 -/* first version to support array filters for "update" command */ -#define WIRE_VERSION_ARRAY_FILTERS 6 -/* first version to support retryable reads */ -#define WIRE_VERSION_RETRY_READS 6 -/* first version to support retryable writes */ -#define WIRE_VERSION_RETRY_WRITES 6 +/* version corresponding to server 3.6 release */ +#define WIRE_VERSION_3_6 6 /* version corresponding to server 4.0 release */ #define WIRE_VERSION_4_0 7 /* first version to support hint for "update" command */ @@ -100,6 +72,19 @@ BSON_BEGIN_DECLS #define WIRE_VERSION_SNAPSHOT_READS 13 /* version corresponding to server 5.1 release */ #define WIRE_VERSION_5_1 14 +/* version corresponding to server 6.0 release */ +#define WIRE_VERSION_6_0 17 +/* version corresponding to server 7.0 release */ +#define WIRE_VERSION_7_0 21 +/* version corresponding to server 7.1 release */ +#define WIRE_VERSION_7_1 22 +#define WIRE_VERSION_MONGOS_EXHAUST 22 + +/* Range of wire protocol versions this driver supports. Bumping + * WIRE_VERSION_MAX must be accompanied by an update to + * `_mongoc_wire_version_to_server_version`. */ +#define WIRE_VERSION_MIN WIRE_VERSION_3_6 /* a.k.a. minWireVersion */ +#define WIRE_VERSION_MAX WIRE_VERSION_7_0 /* a.k.a. maxWireVersion */ struct _mongoc_collection_t; @@ -185,7 +170,7 @@ _mongoc_client_create_stream (mongoc_client_t *client, bool _mongoc_client_recv (mongoc_client_t *client, - mongoc_rpc_t *rpc, + mcd_rpc_message *rpc, mongoc_buffer_t *buffer, mongoc_server_stream_t *server_stream, bson_error_t *error); @@ -246,11 +231,17 @@ mongoc_client_connect (bool buffered, bson_error_t *error); -/* Returns true if a versioned server API has been selected, - * otherwise returns false. */ +/* Returns true if a versioned server API has been selected, otherwise returns + * false. */ bool mongoc_client_uses_server_api (const mongoc_client_t *client); + +/* Returns true if load balancing mode has been selected, otherwise returns + * false. */ +bool +mongoc_client_uses_loadbalanced (const mongoc_client_t *client); + BSON_END_DECLS #endif /* MONGOC_CLIENT_PRIVATE_H */ diff --git a/src/mongoc/mongoc-client-session.c b/src/mongoc/mongoc-client-session.c index 602b47b5..4293e59b 100644 --- a/src/mongoc/mongoc-client-session.c +++ b/src/mongoc/mongoc-client-session.c @@ -25,6 +25,8 @@ #include "mongoc-read-prefs-private.h" #include "mongoc-error-private.h" +#include + #define WITH_TXN_TIMEOUT_MS (120 * 1000) static void @@ -257,8 +259,8 @@ txn_commit (mongoc_client_session_t *session, * actually apply the error label due to reply being NULL */ _mongoc_client_session_unpin (session); if (reply) { - bson_copy_to_excluding_noinit ( - &reply_local, reply, "errorLabels", NULL); + bsonBuildAppend (*reply, + insert (reply_local, not(key ("errorLabels")))); _mongoc_error_copy_labels_and_upsert ( &reply_local, reply, UNKNOWN_COMMIT_RESULT); } @@ -1102,8 +1104,12 @@ mongoc_client_session_start_transaction (mongoc_client_session_t *session, BSON_ASSERT (session); ret = true; - server_stream = mongoc_cluster_stream_for_writes ( - &session->client->cluster, session, NULL /* reply */, error); + server_stream = + mongoc_cluster_stream_for_writes (&session->client->cluster, + session, + NULL /* deprioritized servers */, + NULL /* reply */, + error); if (!server_stream) { ret = false; GOTO (done); @@ -1252,13 +1258,14 @@ mongoc_client_session_commit_transaction (mongoc_client_session_t *session, /* For testing only, mock out certain kinds of errors. */ if (session->fail_commit_label) { - bson_t labels; + bson_array_builder_t *labels; BSON_ASSERT (reply); bson_init (reply); - BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels); - BSON_APPEND_UTF8 (&labels, "0", session->fail_commit_label); + BSON_APPEND_ARRAY_BUILDER_BEGIN (reply, "errorLabels", &labels); + bson_array_builder_append_utf8 (labels, session->fail_commit_label, -1); + bson_append_array_builder_end (reply, labels); /* Waste the test timeout, if there is one set. */ if (session->with_txn_timeout_ms) { @@ -1380,6 +1387,7 @@ _mongoc_client_session_from_iter (mongoc_client_t *client, bson_error_t *error) { ENTRY; + BSON_ASSERT_PARAM (client); /* must be int64 that fits in uint32 */ if (!BSON_ITER_HOLDS_INT64 (iter) || bson_iter_int64 (iter) > 0xffffffff) { diff --git a/src/mongoc/mongoc-client-side-encryption-private.h b/src/mongoc/mongoc-client-side-encryption-private.h index 70f70de3..e9533bb6 100644 --- a/src/mongoc/mongoc-client-side-encryption-private.h +++ b/src/mongoc/mongoc-client-side-encryption-private.h @@ -62,4 +62,48 @@ _mongoc_cse_client_pool_enable_auto_encryption ( bool _mongoc_cse_is_enabled (mongoc_client_t *client); +/** + * @brief The context for the automatic creation of a datakey + */ +struct auto_datakey_context { + /// The output destination for the new key ID. Never NULL. + bson_value_t *out_keyid; + /// An error output destination for the key generation. May be NULL. + bson_error_t *out_error; + /// The userdata pointer given to @ref + /// _mongoc_encryptedFields_fill_auto_datakeys + void *userdata; +}; + +/** + * @brief The type of a datakey-creating callback. + * + * @param ctx The context of the keyId request. @sa auto_datakey_context + * @retval true Upon success + * @retval false Otherwise. + * + * @note Errors should be written into `ctx->out_error`. + */ +typedef bool (*auto_datakey_factory) (struct auto_datakey_context *ctx); + +/** + * @brief Process an array of encryptedFields.fields, automatically filling null + * keyId elements by calling the given factory function. + * + * @param[out] out_fields The modified encryptedFields.fields. Must be destroyed + * by the caller. + * @param[in] in_fields The input encryptedFields.fields + * @param factory A keyId factory. @see auto_datakey_factory + * @param userdata The userdata pointer for `factory` + * @param[out] error An error output parameter + * @retval true On success + * @retval false Otherwise + */ +bool +_mongoc_encryptedFields_fill_auto_datakeys (bson_t *out_fields, + const bson_t *in_fields, + auto_datakey_factory factory, + void *userdata, + bson_error_t *error); + #endif /* MONGOC_CLIENT_SIDE_ENCRYPTION_PRIVATE_H */ diff --git a/src/mongoc/mongoc-client-side-encryption.c b/src/mongoc/mongoc-client-side-encryption.c index 49538d85..2e344f35 100644 --- a/src/mongoc/mongoc-client-side-encryption.c +++ b/src/mongoc/mongoc-client-side-encryption.c @@ -19,6 +19,8 @@ #include #endif +#include + #include "mongoc.h" #include "mongoc-client-private.h" #include "mongoc-client-side-encryption-private.h" @@ -26,6 +28,7 @@ #include "mongoc-stream-private.h" #include "mongoc-topology-private.h" #include "mongoc-trace-private.h" +#include "mongoc-database-private.h" #include "mongoc-util-private.h" /*-------------------------------------------------------------------------- @@ -342,9 +345,7 @@ static void _clear_datakey_keyaltnames (mongoc_client_encryption_datakey_opts_t *opts) { if (opts->keyaltnames) { - int i; - - for (i = 0; i < opts->keyaltnames_count; i++) { + for (uint32_t i = 0u; i < opts->keyaltnames_count; i++) { bson_free (opts->keyaltnames[i]); } bson_free (opts->keyaltnames); @@ -388,8 +389,6 @@ mongoc_client_encryption_datakey_opts_set_keyaltnames ( char **keyaltnames, uint32_t keyaltnames_count) { - int i; - if (!opts) { return; } @@ -400,7 +399,7 @@ mongoc_client_encryption_datakey_opts_set_keyaltnames ( if (keyaltnames_count) { opts->keyaltnames = bson_malloc (sizeof (char *) * keyaltnames_count); - for (i = 0; i < keyaltnames_count; i++) { + for (uint32_t i = 0u; i < keyaltnames_count; i++) { opts->keyaltnames[i] = bson_strdup (keyaltnames[i]); } opts->keyaltnames_count = keyaltnames_count; @@ -430,6 +429,22 @@ mongoc_client_encryption_datakey_opts_set_keymaterial ( * Explicit Encryption options. *-------------------------------------------------------------------------- */ +struct _mongoc_client_encryption_encrypt_range_opts_t { + struct { + bson_value_t value; + bool set; + } min; + struct { + bson_value_t value; + bool set; + } max; + int64_t sparsity; + struct { + int32_t value; + bool set; + } precision; +}; + struct _mongoc_client_encryption_encrypt_opts_t { bson_value_t keyid; char *algorithm; @@ -439,6 +454,7 @@ struct _mongoc_client_encryption_encrypt_opts_t { bool set; } contention_factor; char *query_type; + mongoc_client_encryption_encrypt_range_opts_t *range_opts; }; mongoc_client_encryption_encrypt_opts_t * @@ -447,6 +463,23 @@ mongoc_client_encryption_encrypt_opts_new (void) return bson_malloc0 (sizeof (mongoc_client_encryption_encrypt_opts_t)); } +void +mongoc_client_encryption_encrypt_range_opts_destroy ( + mongoc_client_encryption_encrypt_range_opts_t *range_opts) +{ + if (!range_opts) { + return; + } + + if (range_opts->min.set) { + bson_value_destroy (&range_opts->min.value); + } + if (range_opts->max.set) { + bson_value_destroy (&range_opts->max.value); + } + bson_free (range_opts); +} + void mongoc_client_encryption_encrypt_opts_destroy ( mongoc_client_encryption_encrypt_opts_t *opts) @@ -454,6 +487,7 @@ mongoc_client_encryption_encrypt_opts_destroy ( if (!opts) { return; } + mongoc_client_encryption_encrypt_range_opts_destroy (opts->range_opts); bson_value_destroy (&opts->keyid); bson_free (opts->algorithm); bson_free (opts->keyaltname); @@ -521,6 +555,100 @@ mongoc_client_encryption_encrypt_opts_set_query_type ( opts->query_type = query_type ? bson_strdup (query_type) : NULL; } +/*-------------------------------------------------------------------------- + * Explicit Encryption Range Options + *-------------------------------------------------------------------------- + */ +mongoc_client_encryption_encrypt_range_opts_t * +mongoc_client_encryption_encrypt_range_opts_new (void) +{ + return bson_malloc0 (sizeof (mongoc_client_encryption_encrypt_range_opts_t)); +} + +void +mongoc_client_encryption_encrypt_range_opts_set_sparsity ( + mongoc_client_encryption_encrypt_range_opts_t *range_opts, int64_t sparsity) +{ + BSON_ASSERT_PARAM (range_opts); + range_opts->sparsity = sparsity; +} + +void +mongoc_client_encryption_encrypt_range_opts_set_min ( + mongoc_client_encryption_encrypt_range_opts_t *range_opts, + const bson_value_t *min) +{ + BSON_ASSERT_PARAM (range_opts); + BSON_ASSERT_PARAM (min); + + if (range_opts->min.set) { + bson_value_destroy (&range_opts->min.value); + } + range_opts->min.set = true; + bson_value_copy (min, &range_opts->min.value); +} + +void +mongoc_client_encryption_encrypt_range_opts_set_max ( + mongoc_client_encryption_encrypt_range_opts_t *range_opts, + const bson_value_t *max) +{ + BSON_ASSERT_PARAM (range_opts); + BSON_ASSERT_PARAM (max); + + if (range_opts->max.set) { + bson_value_destroy (&range_opts->max.value); + } + range_opts->max.set = true; + bson_value_copy (max, &range_opts->max.value); +} + +void +mongoc_client_encryption_encrypt_range_opts_set_precision ( + mongoc_client_encryption_encrypt_range_opts_t *range_opts, int32_t precision) +{ + BSON_ASSERT_PARAM (range_opts); + range_opts->precision.set = true; + range_opts->precision.value = precision; +} + +static mongoc_client_encryption_encrypt_range_opts_t * +copy_range_opts (const mongoc_client_encryption_encrypt_range_opts_t *opts) +{ + BSON_ASSERT_PARAM (opts); + mongoc_client_encryption_encrypt_range_opts_t *opts_new = + mongoc_client_encryption_encrypt_range_opts_new (); + if (opts->min.set) { + bson_value_copy (&opts->min.value, &opts_new->min.value); + opts_new->min.set = true; + } + if (opts->max.set) { + bson_value_copy (&opts->max.value, &opts_new->max.value); + opts_new->max.set = true; + } + if (opts->precision.set) { + opts_new->precision.value = opts->precision.value; + opts_new->precision.set = true; + } + opts_new->sparsity = opts->sparsity; + return opts_new; +} + +void +mongoc_client_encryption_encrypt_opts_set_range_opts ( + mongoc_client_encryption_encrypt_opts_t *opts, + const mongoc_client_encryption_encrypt_range_opts_t *range_opts) +{ + BSON_ASSERT_PARAM (opts); + + if (opts->range_opts) { + mongoc_client_encryption_encrypt_range_opts_destroy (opts->range_opts); + opts->range_opts = NULL; + } + + opts->range_opts = copy_range_opts (range_opts); +} + /*-------------------------------------------------------------------------- * RewrapManyDataKeyResult. *-------------------------------------------------------------------------- @@ -645,7 +773,7 @@ bool mongoc_client_encryption_create_datakey ( mongoc_client_encryption_t *client_encryption, const char *kms_provider, - mongoc_client_encryption_datakey_opts_t *opts, + const mongoc_client_encryption_datakey_opts_t *opts, bson_value_t *keyid, bson_error_t *error) { @@ -810,6 +938,25 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption, return _disabled_error (error); } +bool +mongoc_client_encryption_encrypt_expression ( + mongoc_client_encryption_t *client_encryption, + const bson_t *expr, + mongoc_client_encryption_encrypt_opts_t *opts, + bson_t *expr_encrypted, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (client_encryption); + BSON_ASSERT_PARAM (expr); + BSON_ASSERT_PARAM (opts); + BSON_ASSERT_PARAM (expr_encrypted); + BSON_ASSERT (error || true); + + bson_init (expr_encrypted); + + return _disabled_error (error); +} + bool mongoc_client_encryption_decrypt (mongoc_client_encryption_t *client_encryption, const bson_value_t *ciphertext, @@ -834,8 +981,59 @@ _mongoc_cse_is_enabled (mongoc_client_t *client) return false; } +mongoc_collection_t * +mongoc_client_encryption_create_encrypted_collection ( + mongoc_client_encryption_t *enc, + struct _mongoc_database_t *database, + const char *name, + const bson_t *in_options, + bson_t *opt_out_options, + const char *const kms_provider, + const bson_t *opt_masterkey, + bson_error_t *error) +{ + BSON_UNUSED (enc); + BSON_UNUSED (database); + BSON_UNUSED (name); + BSON_UNUSED (in_options); + BSON_UNUSED (opt_out_options); + BSON_UNUSED (kms_provider); + BSON_UNUSED (opt_masterkey); + + _disabled_error (error); + return NULL; +} + #else +/* Appends the range opts set by the user into a bson_t that can be passed to + * libmongocrypt. + */ +static void +append_bson_range_opts (bson_t *bson_range_opts, + const mongoc_client_encryption_encrypt_opts_t *opts) +{ + BSON_ASSERT_PARAM (bson_range_opts); + BSON_ASSERT_PARAM (opts); + + if (opts->range_opts->min.set) { + BSON_ASSERT (BSON_APPEND_VALUE ( + bson_range_opts, "min", &opts->range_opts->min.value)); + } + if (opts->range_opts->max.set) { + BSON_ASSERT (BSON_APPEND_VALUE ( + bson_range_opts, "max", &opts->range_opts->max.value)); + } + if (opts->range_opts->precision.set) { + BSON_ASSERT (BSON_APPEND_INT32 ( + bson_range_opts, "precision", opts->range_opts->precision.value)); + } + if (opts->range_opts->sparsity) { + BSON_ASSERT (BSON_APPEND_INT64 ( + bson_range_opts, "sparsity", opts->range_opts->sparsity)); + } +} + /*-------------------------------------------------------------------------- * * _prep_for_auto_encryption -- @@ -855,7 +1053,8 @@ _prep_for_auto_encryption (const mongoc_cmd_t *cmd, bson_t *out) { /* If there is no type=1 payload, return the command unchanged. */ if (!cmd->payload || !cmd->payload_size) { - bson_init_static (out, bson_get_data (cmd->command), cmd->command->len); + BSON_ASSERT (bson_init_static ( + out, bson_get_data (cmd->command), cmd->command->len)); return; } @@ -872,6 +1071,8 @@ _prep_for_auto_encryption (const mongoc_cmd_t *cmd, bson_t *out) mongoc_client_t * _get_mongocryptd_client (mongoc_client_t *client_encrypted) { + BSON_ASSERT_PARAM (client_encrypted); + if (client_encrypted->topology->single_threaded) { return client_encrypted->topology->mongocryptd_client; } @@ -883,6 +1084,8 @@ void _release_mongocryptd_client (mongoc_client_t *client_encrypted, mongoc_client_t *mongocryptd_client) { + BSON_ASSERT_PARAM (client_encrypted); + if (!mongocryptd_client) { return; } @@ -905,6 +1108,8 @@ _release_mongocryptd_client (mongoc_client_t *client_encrypted, mongoc_collection_t * _get_keyvault_coll (mongoc_client_t *client_encrypted) { + BSON_ASSERT_PARAM (client_encrypted); + mongoc_write_concern_t *const wc = mongoc_write_concern_new (); mongoc_read_concern_t *const rc = mongoc_read_concern_new (); @@ -951,6 +1156,8 @@ _release_keyvault_coll (mongoc_client_t *client_encrypted, { mongoc_client_t *keyvault_client; + BSON_ASSERT_PARAM (client_encrypted); + if (!keyvault_coll) { return; } @@ -1008,6 +1215,7 @@ _mongoc_cse_auto_encrypt (mongoc_client_t *client_encrypted, ENTRY; + BSON_ASSERT_PARAM (client_encrypted); bson_init (encrypted); if (client_encrypted->topology->bypass_auto_encryption) { @@ -1117,6 +1325,7 @@ _mongoc_cse_auto_decrypt (mongoc_client_t *client_encrypted, ENTRY; + BSON_ASSERT_PARAM (client_encrypted); BSON_UNUSED (db_name); keyvault_coll = _get_keyvault_coll (client_encrypted); @@ -1976,7 +2185,7 @@ bool mongoc_client_encryption_create_datakey ( mongoc_client_encryption_t *client_encryption, const char *kms_provider, - mongoc_client_encryption_datakey_opts_t *opts, + const mongoc_client_encryption_datakey_opts_t *opts, bson_value_t *keyid, bson_error_t *error) { @@ -2085,6 +2294,15 @@ mongoc_client_encryption_rewrap_many_datakey ( bson_reinit (bulk_write_result); + if (master_key && !provider) { + bson_set_error ( + error, + MONGOC_ERROR_CLIENT, + MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, + "expected 'provider' to be set to identify type of 'master_key'"); + GOTO (fail); + } + if (!_mongoc_crypt_rewrap_many_datakey (client_encryption->crypt, client_encryption->keyvault_coll, filter, @@ -2569,6 +2787,7 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption, bson_error_t *error) { bool ret = false; + bson_t *range_opts = NULL; ENTRY; @@ -2593,6 +2812,11 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption, GOTO (fail); } + if (opts->range_opts) { + range_opts = bson_new (); + append_bson_range_opts (range_opts, opts); + } + if (!_mongoc_crypt_explicit_encrypt ( client_encryption->crypt, client_encryption->keyvault_coll, @@ -2601,6 +2825,7 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption, opts->keyaltname, opts->query_type, opts->contention_factor.set ? &opts->contention_factor.value : NULL, + range_opts, value, ciphertext, error)) { @@ -2609,9 +2834,54 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption, ret = true; fail: + bson_destroy (range_opts); RETURN (ret); } + +bool +mongoc_client_encryption_encrypt_expression ( + mongoc_client_encryption_t *client_encryption, + const bson_t *expr, + mongoc_client_encryption_encrypt_opts_t *opts, + bson_t *expr_out, + bson_error_t *error) +{ + ENTRY; + + BSON_ASSERT_PARAM (client_encryption); + BSON_ASSERT_PARAM (expr); + BSON_ASSERT_PARAM (opts); + BSON_ASSERT_PARAM (expr_out); + BSON_ASSERT (error || true); + + bson_init (expr_out); + + bson_t *range_opts = NULL; + if (opts->range_opts) { + range_opts = bson_new (); + append_bson_range_opts (range_opts, opts); + } + + if (!_mongoc_crypt_explicit_encrypt_expression ( + client_encryption->crypt, + client_encryption->keyvault_coll, + opts->algorithm, + &opts->keyid, + opts->keyaltname, + opts->query_type, + opts->contention_factor.set ? &opts->contention_factor.value : NULL, + range_opts, + expr, + expr_out, + error)) { + bson_destroy (range_opts); + RETURN (false); + } + bson_destroy (range_opts); + RETURN (true); +} + bool mongoc_client_encryption_decrypt (mongoc_client_encryption_t *client_encryption, const bson_value_t *ciphertext, @@ -2661,6 +2931,8 @@ mongoc_client_encryption_decrypt (mongoc_client_encryption_t *client_encryption, bool _mongoc_cse_is_enabled (mongoc_client_t *client) { + BSON_ASSERT_PARAM (client); + while (1) { mongoc_topology_cse_state_t state = bson_atomic_int_fetch ( (int *) &client->topology->cse_state, bson_memory_order_relaxed); @@ -2672,8 +2944,262 @@ _mongoc_cse_is_enabled (mongoc_client_t *client) } } +/// Context for creating a new datakey using an existing ClientEncryption state +struct cec_context { + mongoc_client_encryption_t *enc; + const mongoc_client_encryption_datakey_opts_t *dk_opts; + const char *kms_provider; +}; + +/// Automatically create a new datakey. @see auto_datakey_factory +static bool +_auto_datakey (struct auto_datakey_context *ctx) +{ + struct cec_context *cec = ctx->userdata; + return mongoc_client_encryption_create_datakey (cec->enc, + cec->kms_provider, + cec->dk_opts, + ctx->out_keyid, + ctx->out_error); +} + +mongoc_collection_t * +mongoc_client_encryption_create_encrypted_collection ( + mongoc_client_encryption_t *enc, + struct _mongoc_database_t *database, + const char *name, + const bson_t *in_options, + bson_t *opt_out_options, + const char *const kms_provider, + const bson_t *opt_masterkey, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (enc); + BSON_ASSERT_PARAM (database); + BSON_ASSERT_PARAM (name); + BSON_ASSERT_PARAM (in_options); + BSON_ASSERT (opt_out_options || true); + BSON_ASSERT_PARAM (kms_provider); + BSON_ASSERT (error || true); + + mongoc_collection_t *ret = NULL; + + bson_t in_encryptedFields = BSON_INITIALIZER; + bson_t new_encryptedFields = BSON_INITIALIZER; + bson_t local_new_options = BSON_INITIALIZER; + + mongoc_client_encryption_datakey_opts_t *dk_opts = + mongoc_client_encryption_datakey_opts_new (); + if (opt_masterkey) { + mongoc_client_encryption_datakey_opts_set_masterkey (dk_opts, + opt_masterkey); + } + + if (!opt_out_options) { + // We'll use our own storage for the new options + opt_out_options = &local_new_options; + } + + // Init the storage. Either inits the caller's copy, or our local version. + bson_init (opt_out_options); + + // Look up the encryptedfields that we should use for this collection. They + // may be in the given options, or they may be in the encryptedFieldsMap. + if (!_mongoc_get_collection_encryptedFields ( + database->client, + mongoc_database_get_name (database), + name, + in_options, + false /* checkEncryptedFieldsMap */, + &in_encryptedFields, + error)) { + // Error finding the encryptedFields + goto done; + } + + if (bson_empty (&in_encryptedFields)) { + bson_set_error (error, + MONGOC_ERROR_COMMAND, + MONGOC_ERROR_COMMAND_INVALID_ARG, + "No 'encryptedFields' are defined for the creation of " + "the '%s' collection", + name); + goto done; + } + + // Add the keyIds to the encryptedFields. + // Context for the creation of new datakeys: + struct cec_context ctx = { + .enc = enc, + .dk_opts = dk_opts, + .kms_provider = kms_provider, + }; + bson_t fields_ref; + bsonVisitEach ( + in_encryptedFields, + case ( + // We only care about the "fields" array + when (not(key ("fields")), appendTo (new_encryptedFields)), + // Automaticall fill in the "keyId" no each field: + else ( + storeDocRef (fields_ref), do ({ + bson_t new_fields = BSON_INITIALIZER; + // Create the new fields, filling out the 'keyId' + // automatically: + if (!_mongoc_encryptedFields_fill_auto_datakeys ( + &new_fields, &fields_ref, _auto_datakey, &ctx, error)) { + bsonParseError = "Error creating datakeys"; + } else { + BSON_APPEND_ARRAY ( + &new_encryptedFields, "fields", &new_fields); + bson_destroy (&new_fields); + } + })))); + if (bsonParseError) { + // Error creating the new datakeys. + // `error` was set by _mongoc_encryptedFields_fill_auto_datakeys + goto done; + } + + // We've successfully filled out all null keyIds. Now create the collection + // with our new options: + bsonBuild (*opt_out_options, + insert (*in_options, not(key ("encryptedFields"))), + kv ("encryptedFields", bson (new_encryptedFields))); + if (bsonBuildError) { + // Error while building the new options. + bson_set_error (error, + MONGOC_ERROR_BSON, + MONGOC_ERROR_BSON_INVALID, + "Error while building new createCollection options: %s", + bsonBuildError); + goto done; + } + + ret = mongoc_database_create_collection ( + database, name, opt_out_options, error); + +done: + bson_destroy (&new_encryptedFields); + bson_destroy (&in_encryptedFields); + mongoc_client_encryption_datakey_opts_destroy (dk_opts); + // Destroy the local options, which may or may not have been used. If unused, + // the new options are now owned by the caller and this is a no-op. + bson_destroy (&local_new_options); + // The resulting collection, or NULL on error: + return ret; +} + #endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */ +/// Generate one encryptedField element. +static void +_init_1_encryptedField (bson_t *out_field, + const bson_t *in_field, + auto_datakey_factory fac, + void *fac_userdata, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (out_field); + BSON_ASSERT_PARAM (in_field); + BSON_ASSERT_PARAM (fac); + BSON_ASSERT (fac_userdata || true); + BSON_ASSERT (error || true); + bsonVisitEach ( + *in_field, + // If it is not a "keyId":null element, just copy it to the output. + if (not(keyWithType ("keyId", null)), + then (appendTo (*out_field), continue)), + // Otherwise: + do ({ + // Set up factory context + bson_value_t new_key = {0}; + struct auto_datakey_context ctx = { + .out_keyid = &new_key, + .out_error = error, + .userdata = fac_userdata, + }; + // Call the callback to create the new key + if (!fac (&ctx)) { + bsonParseError = "Factory function indicated failure"; + } else { + // Append to the field + BSON_APPEND_VALUE (out_field, "keyId", &new_key); + } + bson_value_destroy (&new_key); + })); +} + +/// Generate the "encryptedFields" output for auto-datakeys +static void +_init_encryptedFields (bson_t *out_fields, + const bson_t *in_fields, + auto_datakey_factory fac, + void *fac_userdata, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (out_fields); + BSON_ASSERT_PARAM (in_fields); + BSON_ASSERT_PARAM (fac); + BSON_ASSERT (fac_userdata || true); + BSON_ASSERT (error || true); + // Ref to one encyrptedField + bson_t cur_field; + bsonVisitEach ( + *in_fields, + // Each field must be a document element + if (not(type (doc)), + then (error ("Each 'encryptedFields' element must be a document"))), + // Append a new element with the same name as the field: + storeDocRef (cur_field), + append ( + *out_fields, + kv ( + bson_iter_key (&bsonVisitIter), + // Construct the encryptedField document from the input: + doc (do (_init_1_encryptedField ( + bsonBuildContext.doc, &cur_field, fac, fac_userdata, error)))))); + if (error && error->code == 0) { + // The factory/internal code did not set error, so we may have to set it + // for an error while BSON parsing/generating. + if (bsonParseError) { + bson_set_error (error, + MONGOC_ERROR_BSON, + MONGOC_ERROR_BSON_INVALID, + "Error while generating datakeys: %s", + bsonParseError); + } + if (bsonBuildError) { + bson_set_error (error, + MONGOC_ERROR_BSON, + MONGOC_ERROR_BSON_INVALID, + "Error while generating datakeys: %s", + bsonBuildError); + } + } +} + +bool +_mongoc_encryptedFields_fill_auto_datakeys (bson_t *out_fields, + const bson_t *in_fields, + auto_datakey_factory factory, + void *userdata, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (in_fields); + BSON_ASSERT_PARAM (out_fields); + BSON_ASSERT_PARAM (factory); + + if (error) { + *error = (bson_error_t){0}; + } + bson_init (out_fields); + + _init_encryptedFields (out_fields, in_fields, factory, userdata, error); + + // DSL errors will be set in case of failure + return bsonParseError == NULL && bsonBuildError == NULL; +} const char * mongoc_client_encryption_get_crypt_shared_version ( @@ -2688,8 +3214,10 @@ mongoc_client_encryption_get_crypt_shared_version ( } const char * -mongoc_client_get_crypt_shared_version (const mongoc_client_t *const client) +mongoc_client_get_crypt_shared_version (const mongoc_client_t *client) { + BSON_ASSERT_PARAM (client); + #ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION if (!client->topology->crypt) { return NULL; diff --git a/src/mongoc/mongoc-client-side-encryption.h b/src/mongoc/mongoc-client-side-encryption.h index 6ad0d61b..3a1e8180 100644 --- a/src/mongoc/mongoc-client-side-encryption.h +++ b/src/mongoc/mongoc-client-side-encryption.h @@ -26,14 +26,19 @@ struct _mongoc_client_t; struct _mongoc_client_pool_t; struct _mongoc_cursor_t; +struct _mongoc_collection_t; +struct _mongoc_database_t; + #define MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM \ "AEAD_AES_256_CBC_HMAC_SHA_512-Random" #define MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC \ "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" #define MONGOC_ENCRYPT_ALGORITHM_INDEXED "Indexed" #define MONGOC_ENCRYPT_ALGORITHM_UNINDEXED "Unindexed" +#define MONGOC_ENCRYPT_ALGORITHM_RANGEPREVIEW "RangePreview" #define MONGOC_ENCRYPT_QUERY_TYPE_EQUALITY "equality" +#define MONGOC_ENCRYPT_QUERY_TYPE_RANGEPREVIEW "rangePreview" BSON_BEGIN_DECLS @@ -97,6 +102,8 @@ mongoc_auto_encryption_opts_set_kms_credential_provider_callback ( typedef struct _mongoc_client_encryption_opts_t mongoc_client_encryption_opts_t; typedef struct _mongoc_client_encryption_t mongoc_client_encryption_t; +typedef struct _mongoc_client_encryption_encrypt_range_opts_t + mongoc_client_encryption_encrypt_range_opts_t; typedef struct _mongoc_client_encryption_encrypt_opts_t mongoc_client_encryption_encrypt_opts_t; typedef struct _mongoc_client_encryption_datakey_opts_t @@ -158,7 +165,7 @@ MONGOC_EXPORT (bool) mongoc_client_encryption_create_datakey ( mongoc_client_encryption_t *client_encryption, const char *kms_provider, - mongoc_client_encryption_datakey_opts_t *opts, + const mongoc_client_encryption_datakey_opts_t *opts, bson_value_t *keyid, bson_error_t *error); @@ -218,6 +225,14 @@ mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption, bson_value_t *ciphertext, bson_error_t *error); +MONGOC_EXPORT (bool) +mongoc_client_encryption_encrypt_expression ( + mongoc_client_encryption_t *client_encryption, + const bson_t *expr, + mongoc_client_encryption_encrypt_opts_t *opts, + bson_t *expr_out, + bson_error_t *error); + MONGOC_EXPORT (bool) mongoc_client_encryption_decrypt (mongoc_client_encryption_t *client_encryption, const bson_value_t *ciphertext, @@ -251,6 +266,37 @@ MONGOC_EXPORT (void) mongoc_client_encryption_encrypt_opts_set_query_type ( mongoc_client_encryption_encrypt_opts_t *opts, const char *query_type); +MONGOC_EXPORT (mongoc_client_encryption_encrypt_range_opts_t *) +mongoc_client_encryption_encrypt_range_opts_new (void); + +MONGOC_EXPORT (void) +mongoc_client_encryption_encrypt_range_opts_destroy ( + mongoc_client_encryption_encrypt_range_opts_t *range_opts); + +MONGOC_EXPORT (void) +mongoc_client_encryption_encrypt_range_opts_set_sparsity ( + mongoc_client_encryption_encrypt_range_opts_t *range_opts, int64_t sparsity); + +MONGOC_EXPORT (void) +mongoc_client_encryption_encrypt_range_opts_set_min ( + mongoc_client_encryption_encrypt_range_opts_t *range_opts, + const bson_value_t *min); + +MONGOC_EXPORT (void) +mongoc_client_encryption_encrypt_range_opts_set_max ( + mongoc_client_encryption_encrypt_range_opts_t *range_opts, + const bson_value_t *max); + +MONGOC_EXPORT (void) +mongoc_client_encryption_encrypt_range_opts_set_precision ( + mongoc_client_encryption_encrypt_range_opts_t *range_opts, + int32_t precision); + +MONGOC_EXPORT (void) +mongoc_client_encryption_encrypt_opts_set_range_opts ( + mongoc_client_encryption_encrypt_opts_t *opts, + const mongoc_client_encryption_encrypt_range_opts_t *range_opts); + MONGOC_EXPORT (mongoc_client_encryption_datakey_opts_t *) mongoc_client_encryption_datakey_opts_new (void) BSON_GNUC_WARN_UNUSED_RESULT; @@ -278,6 +324,17 @@ MONGOC_EXPORT (const char *) mongoc_client_encryption_get_crypt_shared_version ( mongoc_client_encryption_t const *enc) BSON_GNUC_WARN_UNUSED_RESULT; +MONGOC_EXPORT (struct _mongoc_collection_t *) +mongoc_client_encryption_create_encrypted_collection ( + mongoc_client_encryption_t *enc, + struct _mongoc_database_t *database, + const char *name, + const bson_t *in_options, + bson_t *opt_out_options, + const char *const kms_provider, + const bson_t *opt_masterkey, + bson_error_t *error) BSON_GNUC_WARN_UNUSED_RESULT; + BSON_END_DECLS #endif /* MONGOC_CLIENT_SIDE_ENCRYPTION_H */ diff --git a/src/mongoc/mongoc-client.c b/src/mongoc/mongoc-client.c index 6fe531fb..7066d4e8 100644 --- a/src/mongoc/mongoc-client.c +++ b/src/mongoc/mongoc-client.c @@ -14,7 +14,6 @@ * limitations under the License. */ - #include #include "mongoc-config.h" #ifdef MONGOC_HAVE_DNSAPI @@ -25,6 +24,7 @@ #else #if defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH) #include +#include #include #include #include @@ -101,7 +101,11 @@ _mongoc_client_killcursors_command (mongoc_cluster_t *cluster, } while (0) -#ifdef MONGOC_HAVE_DNSAPI +#if MONGOC_ENABLE_SRV == 0 // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ ENABLE_SRV disabled + +/* SRV support is disabled */ + +#elif defined(MONGOC_HAVE_DNSAPI) // ↑↑↑ ENABLE_SRV disabled / Win32 Dnsapi ↓↓↓↓ typedef bool (*mongoc_rr_callback_t) (const char *hostname, PDNS_RECORD pdns, @@ -291,7 +295,9 @@ _mongoc_get_rr_dnsapi (const char *hostname, RETURN (dns_success && callback_success); } -#elif (defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH)) +#elif ( \ + defined(MONGOC_HAVE_RES_NSEARCH) || \ + defined(MONGOC_HAVE_RES_SEARCH)) // ↑↑↑↑↑↑↑ Win32 Dnsapi / resolv ↓↓↓↓↓↓↓↓ typedef bool (*mongoc_rr_callback_t) (const char *hostname, ns_msg *ns_answer, @@ -569,7 +575,7 @@ _mongoc_get_rr_search (const char *hostname, #endif RETURN (dns_success && callback_success); } -#endif +#endif // ↑↑↑↑↑↑↑↑↑↑↑↑↑ resolv /* *-------------------------------------------------------------------------- @@ -605,17 +611,20 @@ _mongoc_client_get_rr (const char *hostname, { BSON_ASSERT (rr_data); -#ifdef MONGOC_HAVE_DNSAPI - return _mongoc_get_rr_dnsapi (hostname, rr_type, rr_data, error); -#elif (defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH)) - return _mongoc_get_rr_search ( - hostname, rr_type, rr_data, initial_buffer_size, error); -#else +#if MONGOC_ENABLE_SRV == 0 + // Disabled bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_NAME_RESOLUTION, "libresolv unavailable, cannot use mongodb+srv URI"); return false; +#elif defined(MONGOC_HAVE_DNSAPI) + return _mongoc_get_rr_dnsapi (hostname, rr_type, rr_data, error); +#elif (defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH)) + return _mongoc_get_rr_search ( + hostname, rr_type, rr_data, initial_buffer_size, error); +#else +#error No SRV library is available, but ENABLE_SRV is true! #endif } @@ -944,40 +953,25 @@ _mongoc_client_create_stream (mongoc_client_t *client, const mongoc_host_list_t *host, bson_error_t *error) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (host); return client->initiator (client->uri, host, client->initiator_data, error); } -/* - *-------------------------------------------------------------------------- - * - * _mongoc_client_recv -- - * - * Receives a RPC from a remote MongoDB cluster node. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @error is set if return value is false. - * - *-------------------------------------------------------------------------- - */ - bool _mongoc_client_recv (mongoc_client_t *client, - mongoc_rpc_t *rpc, + mcd_rpc_message *rpc, mongoc_buffer_t *buffer, mongoc_server_stream_t *server_stream, bson_error_t *error) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (rpc); BSON_ASSERT (buffer); BSON_ASSERT (server_stream); + BSON_ASSERT_PARAM (error); return mongoc_cluster_try_recv ( &client->cluster, rpc, buffer, server_stream, error); @@ -1033,6 +1027,7 @@ void _mongoc_client_set_internal_tls_opts (mongoc_client_t *client, _mongoc_internal_tls_opts_t *internal) { + BSON_ASSERT_PARAM (client); if (!client->use_ssl) { return; } @@ -1047,7 +1042,7 @@ void mongoc_client_set_ssl_opts (mongoc_client_t *client, const mongoc_ssl_opt_t *opts) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (opts); _mongoc_ssl_opts_cleanup (&client->ssl_opts, @@ -1245,7 +1240,7 @@ mongoc_client_destroy (mongoc_client_t *client) const mongoc_uri_t * mongoc_client_get_uri (const mongoc_client_t *client) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); return client->uri; } @@ -1274,6 +1269,8 @@ mongoc_client_start_session (mongoc_client_t *client, const mongoc_session_opt_t *opts, bson_error_t *error) { + BSON_ASSERT_PARAM (client); + mongoc_server_session_t *ss; mongoc_client_session_t *cs; uint32_t csid; @@ -1336,7 +1333,7 @@ mongoc_client_start_session (mongoc_client_t *client, mongoc_database_t * mongoc_client_get_database (mongoc_client_t *client, const char *name) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (name); return _mongoc_database_new (client, @@ -1372,7 +1369,7 @@ mongoc_client_get_default_database (mongoc_client_t *client) { const char *db; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); db = mongoc_uri_get_database (client->uri); if (db) { @@ -1413,7 +1410,7 @@ mongoc_client_get_collection (mongoc_client_t *client, const char *db, const char *collection) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (db); BSON_ASSERT (collection); @@ -1455,7 +1452,7 @@ mongoc_client_get_gridfs (mongoc_client_t *client, const char *prefix, bson_error_t *error) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (db); if (!prefix) { @@ -1485,7 +1482,7 @@ mongoc_client_get_gridfs (mongoc_client_t *client, const mongoc_write_concern_t * mongoc_client_get_write_concern (const mongoc_client_t *client) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); return client->write_concern; } @@ -1511,7 +1508,7 @@ void mongoc_client_set_write_concern (mongoc_client_t *client, const mongoc_write_concern_t *write_concern) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); if (write_concern != client->write_concern) { if (client->write_concern) { @@ -1543,7 +1540,7 @@ mongoc_client_set_write_concern (mongoc_client_t *client, const mongoc_read_concern_t * mongoc_client_get_read_concern (const mongoc_client_t *client) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); return client->read_concern; } @@ -1569,7 +1566,7 @@ void mongoc_client_set_read_concern (mongoc_client_t *client, const mongoc_read_concern_t *read_concern) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); if (read_concern != client->read_concern) { if (client->read_concern) { @@ -1601,7 +1598,7 @@ mongoc_client_set_read_concern (mongoc_client_t *client, const mongoc_read_prefs_t * mongoc_client_get_read_prefs (const mongoc_client_t *client) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); return client->read_prefs; } @@ -1627,7 +1624,7 @@ void mongoc_client_set_read_prefs (mongoc_client_t *client, const mongoc_read_prefs_t *read_prefs) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); if (read_prefs != client->read_prefs) { if (client->read_prefs) { @@ -1659,7 +1656,7 @@ mongoc_client_command (mongoc_client_t *client, BSON_UNUSED (batch_size); BSON_UNUSED (fields); - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (db_name); BSON_ASSERT (query); @@ -1694,6 +1691,7 @@ _mongoc_client_retryable_write_command_with_stream ( ENTRY; + BSON_ASSERT_PARAM (client); BSON_ASSERT (parts->is_retryable_write); /* increment the transaction number for the first attempt of each retryable @@ -1703,12 +1701,18 @@ _mongoc_client_retryable_write_command_with_stream ( bson_iter_overwrite_int64 ( &txn_number_iter, ++parts->assembled.session->server_session->txn_number); + // Store the original error and reply if needed. + struct { + bson_t reply; + bson_error_t error; + bool set; + } original_error = {.reply = {0}, .error = {0}, false}; + retry: ret = mongoc_cluster_run_command_monitored ( &client->cluster, &parts->assembled, reply, error); - _mongoc_write_error_handle_labels ( - ret, error, reply, server_stream->sd->max_wire_version); + _mongoc_write_error_handle_labels (ret, error, reply, server_stream->sd); if (is_retryable) { _mongoc_write_error_update_if_unsupported_storage_engine ( @@ -1723,19 +1727,38 @@ _mongoc_client_retryable_write_command_with_stream ( _mongoc_write_error_get_type (reply) == MONGOC_WRITE_ERR_RETRY) { bson_error_t ignored_error; - /* each write command may be retried at most once */ + // The write command may be retried at most once. is_retryable = false; - if (retry_server_stream) { - mongoc_server_stream_cleanup (retry_server_stream); - } + { + mongoc_deprioritized_servers_t *const ds = + mongoc_deprioritized_servers_new (); - retry_server_stream = mongoc_cluster_stream_for_writes ( - &client->cluster, parts->assembled.session, NULL, &ignored_error); + mongoc_deprioritized_servers_add_if_sharded ( + ds, server_stream->topology_type, server_stream->sd); - if (retry_server_stream && retry_server_stream->sd->max_wire_version >= - WIRE_VERSION_RETRY_WRITES) { + BSON_ASSERT (!retry_server_stream); + retry_server_stream = + mongoc_cluster_stream_for_writes (&client->cluster, + parts->assembled.session, + ds, + NULL, + &ignored_error); + + mongoc_deprioritized_servers_destroy (ds); + } + + if (retry_server_stream) { parts->assembled.server_stream = retry_server_stream; + { + // Store the original error and reply before retry. + BSON_ASSERT (!original_error.set); // Retry only happens once. + original_error.set = true; + bson_copy_to (reply, &original_error.reply); + if (error) { + original_error.error = *error; + } + } bson_destroy (reply); GOTO (retry); } @@ -1745,6 +1768,21 @@ _mongoc_client_retryable_write_command_with_stream ( mongoc_server_stream_cleanup (retry_server_stream); } + // If a retry attempt fails with an error labeled NoWritesPerformed, + // drivers MUST return the original error. + if (original_error.set && + mongoc_error_has_label (reply, "NoWritesPerformed")) { + if (error) { + *error = original_error.error; + } + bson_destroy (reply); + bson_copy_to (&original_error.reply, reply); + } + + if (original_error.set) { + bson_destroy (&original_error.reply); + } + if (ret && error) { /* if a retry succeeded, clear the initial error */ memset (error, 0, sizeof (bson_error_t)); @@ -1767,6 +1805,7 @@ _mongoc_client_retryable_read_command_with_stream ( bool ret; bson_t reply_local; + BSON_ASSERT_PARAM (client); BSON_UNUSED (server_stream); if (reply == NULL) { @@ -1792,20 +1831,31 @@ _mongoc_client_retryable_read_command_with_stream ( /* each read command may be retried at most once */ is_retryable = false; - if (retry_server_stream) { - mongoc_server_stream_cleanup (retry_server_stream); - } + { + mongoc_deprioritized_servers_t *const ds = + mongoc_deprioritized_servers_new (); - retry_server_stream = - mongoc_cluster_stream_for_reads (&client->cluster, - parts->read_prefs, - parts->assembled.session, - NULL, - /* Not aggregate-with-write */ false, - &ignored_error); + if (retry_server_stream) { + mongoc_deprioritized_servers_add_if_sharded ( + ds, retry_server_stream->topology_type, retry_server_stream->sd); + mongoc_server_stream_cleanup (retry_server_stream); + } else { + mongoc_deprioritized_servers_add_if_sharded ( + ds, server_stream->topology_type, server_stream->sd); + } + + retry_server_stream = + mongoc_cluster_stream_for_reads (&client->cluster, + parts->read_prefs, + parts->assembled.session, + ds, + NULL, + &ignored_error); - if (retry_server_stream && retry_server_stream->sd->max_wire_version >= - WIRE_VERSION_RETRY_READS) { + mongoc_deprioritized_servers_destroy (ds); + } + + if (retry_server_stream) { parts->assembled.server_stream = retry_server_stream; bson_destroy (reply); GOTO (retry); @@ -1835,6 +1885,7 @@ _mongoc_client_command_with_stream (mongoc_client_t *client, { ENTRY; + BSON_ASSERT_PARAM (client); BSON_UNUSED (read_prefs); parts->assembled.operation_id = ++client->cluster.operation_id; @@ -1873,7 +1924,7 @@ mongoc_client_command_simple (mongoc_client_t *client, ENTRY; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (db_name); BSON_ASSERT (command); @@ -1891,13 +1942,8 @@ mongoc_client_command_simple (mongoc_client_t *client, * configuration. The generic command method SHOULD allow an optional read * preference argument." */ - server_stream = - mongoc_cluster_stream_for_reads (cluster, - read_prefs, - NULL, - reply, - /* Not aggregate-with-write */ false, - error); + server_stream = mongoc_cluster_stream_for_reads ( + cluster, read_prefs, NULL, NULL, reply, error); if (server_stream) { ret = _mongoc_client_command_with_stream ( @@ -1965,14 +2011,12 @@ _mongoc_client_command_with_opts (mongoc_client_t *client, mongoc_client_session_t *cs; bson_t reply_local; bson_t *reply_ptr; - int32_t wire_version; - int32_t wc_wire_version; bool reply_initialized = false; bool ret = false; ENTRY; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (db_name); BSON_ASSERT (command); @@ -2054,15 +2098,10 @@ _mongoc_client_command_with_opts (mongoc_client_t *client, } } else if (parts.is_write_command) { server_stream = - mongoc_cluster_stream_for_writes (cluster, cs, reply_ptr, error); + mongoc_cluster_stream_for_writes (cluster, cs, NULL, reply_ptr, error); } else { - server_stream = - mongoc_cluster_stream_for_reads (cluster, - prefs, - cs, - reply_ptr, - /* Not aggregate-with-write */ false, - error); + server_stream = mongoc_cluster_stream_for_reads ( + cluster, prefs, cs, NULL, reply_ptr, error); } if (!server_stream) { @@ -2071,36 +2110,15 @@ _mongoc_client_command_with_opts (mongoc_client_t *client, GOTO (done); } - wire_version = server_stream->sd->max_wire_version; - if (!mongoc_cmd_parts_append_read_write ( - &parts, &read_write_opts, wire_version, error)) { + if (!mongoc_cmd_parts_append_read_write (&parts, &read_write_opts, error)) { GOTO (done); } if (mode & MONGOC_CMD_WRITE) { - wc_wire_version = !strcasecmp (command_name, "findandmodify") - ? WIRE_VERSION_FAM_WRITE_CONCERN - : WIRE_VERSION_CMD_WRITE_CONCERN; - - if (read_write_opts.write_concern_owned && - wire_version < wc_wire_version) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "\"%s\" command does not support writeConcern with " - "wire version %d, wire version %d is required", - command_name, - wire_version, - wc_wire_version); - GOTO (done); - } - /* use default write concern unless it's in opts */ if (!mongoc_write_concern_is_default (default_wc) && - !read_write_opts.write_concern_owned && - wire_version >= wc_wire_version) { - if (!mongoc_cmd_parts_set_write_concern ( - &parts, default_wc, wire_version, error)) { + !read_write_opts.write_concern_owned) { + if (!mongoc_cmd_parts_set_write_concern (&parts, default_wc, error)) { GOTO (done); } } @@ -2108,8 +2126,7 @@ _mongoc_client_command_with_opts (mongoc_client_t *client, /* use default read concern for read command, unless it's in opts */ if ((mode & MONGOC_CMD_READ) && bson_empty (&read_write_opts.readConcern)) { - if (!mongoc_cmd_parts_set_read_concern ( - &parts, default_rc, wire_version, error)) { + if (!mongoc_cmd_parts_set_read_concern (&parts, default_rc, error)) { GOTO (done); } } @@ -2255,7 +2272,7 @@ mongoc_client_command_simple_with_server_id ( ENTRY; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (db_name); BSON_ASSERT (command); @@ -2289,12 +2306,12 @@ _mongoc_client_prepare_killcursors_command (int64_t cursor_id, const char *collection, bson_t *command) { - bson_t child; + bson_array_builder_t *child; bson_append_utf8 (command, "killCursors", 11, collection, -1); - bson_append_array_begin (command, "cursors", 7, &child); - bson_append_int64 (&child, "0", 1, cursor_id); - bson_append_array_end (command, &child); + bson_append_array_builder_begin (command, "cursors", 7, &child); + bson_array_builder_append_int64 (child, cursor_id); + bson_append_array_builder_end (command, child); } @@ -2311,7 +2328,7 @@ _mongoc_client_kill_cursor (mongoc_client_t *client, ENTRY; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (cursor_id); /* don't attempt reconnect if server unavailable, and ignore errors */ @@ -2322,8 +2339,7 @@ _mongoc_client_kill_cursor (mongoc_client_t *client, return; } - if (db && collection && - server_stream->sd->max_wire_version >= WIRE_VERSION_KILLCURSORS_CMD) { + if (db && collection) { _mongoc_client_killcursors_command ( &client->cluster, server_stream, cursor_id, db, collection, cs); } else { @@ -2394,7 +2410,7 @@ _mongoc_client_monitor_op_killcursors_succeeded ( { mongoc_client_t *client; bson_t doc; - bson_t cursors_unknown; + bson_array_builder_t *cursors_unknown; mongoc_apm_command_succeeded_t event; ENTRY; @@ -2408,9 +2424,10 @@ _mongoc_client_monitor_op_killcursors_succeeded ( /* fake server reply to killCursors command: {ok: 1, cursorsUnknown: [42]} */ bson_init (&doc); bson_append_int32 (&doc, "ok", 2, 1); - bson_append_array_begin (&doc, "cursorsUnknown", 14, &cursors_unknown); - bson_append_int64 (&cursors_unknown, "0", 1, cursor_id); - bson_append_array_end (&doc, &cursors_unknown); + bson_append_array_builder_begin ( + &doc, "cursorsUnknown", 14, &cursors_unknown); + bson_array_builder_append_int64 (cursors_unknown, cursor_id); + bson_append_array_builder_end (&doc, cursors_unknown); mongoc_apm_command_succeeded_init (&event, duration, @@ -2485,36 +2502,44 @@ _mongoc_client_op_killcursors (mongoc_cluster_t *cluster, const char *db, const char *collection) { - int64_t started; - mongoc_rpc_t rpc = {{0}}; - bson_error_t error; - bool has_ns; - bool r; + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT_PARAM (server_stream); + BSON_ASSERT (db || true); + BSON_ASSERT (collection || true); + + const bool has_ns = db && collection; + const int64_t started = bson_get_monotonic_time (); + + mcd_rpc_message *const rpc = mcd_rpc_message_new (); - /* called by old mongoc_client_kill_cursor without db/collection? */ - has_ns = (db && collection); - started = bson_get_monotonic_time (); + { + int32_t message_length = 0; - ++cluster->request_id; + message_length += mcd_rpc_header_set_message_length (rpc, 0); + message_length += + mcd_rpc_header_set_request_id (rpc, ++cluster->request_id); + message_length += mcd_rpc_header_set_response_to (rpc, 0); + message_length += + mcd_rpc_header_set_op_code (rpc, MONGOC_OP_CODE_KILL_CURSORS); - rpc.header.msg_len = 0; - rpc.header.request_id = cluster->request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_KILL_CURSORS; - rpc.kill_cursors.zero = 0; - rpc.kill_cursors.cursors = &cursor_id; - rpc.kill_cursors.n_cursors = 1; + message_length += sizeof (int32_t); // ZERO + message_length += + mcd_rpc_op_kill_cursors_set_cursor_ids (rpc, &cursor_id, 1); + + mcd_rpc_message_set_length (rpc, message_length); + } if (has_ns) { _mongoc_client_monitor_op_killcursors ( cluster, server_stream, cursor_id, operation_id, db, collection); } - r = mongoc_cluster_legacy_rpc_sendv_to_server ( - cluster, &rpc, server_stream, &error); + bson_error_t error; + const bool res = mongoc_cluster_legacy_rpc_sendv_to_server ( + cluster, rpc, server_stream, &error); if (has_ns) { - if (r) { + if (res) { _mongoc_client_monitor_op_killcursors_succeeded ( cluster, bson_get_monotonic_time () - started, @@ -2530,6 +2555,8 @@ _mongoc_client_op_killcursors (mongoc_cluster_t *cluster, operation_id); } } + + mcd_rpc_message_destroy (rpc); } @@ -2594,6 +2621,8 @@ _mongoc_client_killcursors_command (mongoc_cluster_t *cluster, void mongoc_client_kill_cursor (mongoc_client_t *client, int64_t cursor_id) { + BSON_ASSERT_PARAM (client); + mongoc_topology_t *const topology = BSON_ASSERT_PTR_INLINE (client)->topology; mongoc_server_description_t const *selected_server; @@ -2617,6 +2646,7 @@ mongoc_client_kill_cursor (mongoc_client_t *client, int64_t cursor_id) MONGOC_SS_WRITE, read_prefs, NULL /* chosen read mode */, + NULL /* deprioritized servers */, topology->local_threshold_msec); if (selected_server) { @@ -2660,7 +2690,7 @@ mongoc_client_get_database_names_with_opts (mongoc_client_t *client, const bson_t *doc; bson_t cmd = BSON_INITIALIZER; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_APPEND_INT32 (&cmd, "listDatabases", 1); BSON_APPEND_BOOL (&cmd, "nameOnly", true); @@ -2691,6 +2721,7 @@ mongoc_client_get_database_names_with_opts (mongoc_client_t *client, mongoc_cursor_t * mongoc_client_find_databases (mongoc_client_t *client, bson_error_t *error) { + BSON_ASSERT_PARAM (client); BSON_UNUSED (error); /* existing bug in this deprecated API: error pointer is unused */ @@ -2705,7 +2736,7 @@ mongoc_client_find_databases_with_opts (mongoc_client_t *client, bson_t cmd = BSON_INITIALIZER; mongoc_cursor_t *cursor; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_APPEND_INT32 (&cmd, "listDatabases", 1); cursor = _mongoc_cursor_array_new (client, "admin", &cmd, opts, "databases"); bson_destroy (&cmd); @@ -2716,7 +2747,7 @@ mongoc_client_find_databases_with_opts (mongoc_client_t *client, int32_t mongoc_client_get_max_message_size (mongoc_client_t *client) /* IN */ { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); return mongoc_cluster_get_max_msg_size (&client->cluster); } @@ -2725,7 +2756,7 @@ mongoc_client_get_max_message_size (mongoc_client_t *client) /* IN */ int32_t mongoc_client_get_max_bson_size (mongoc_client_t *client) /* IN */ { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); return mongoc_cluster_get_max_bson_obj_size (&client->cluster); } @@ -2740,7 +2771,7 @@ mongoc_client_get_server_status (mongoc_client_t *client, /* IN */ bson_t cmd = BSON_INITIALIZER; bool ret = false; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_APPEND_INT32 (&cmd, "serverStatus", 1); ret = mongoc_client_command_simple ( @@ -2756,7 +2787,7 @@ mongoc_client_set_stream_initiator (mongoc_client_t *client, mongoc_stream_initiator_t initiator, void *user_data) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); if (!initiator) { initiator = mongoc_client_default_stream_initiator; @@ -2780,6 +2811,8 @@ _mongoc_client_set_apm_callbacks_private (mongoc_client_t *client, mongoc_apm_callbacks_t *callbacks, void *context) { + BSON_ASSERT_PARAM (client); + if (callbacks) { memcpy ( &client->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t)); @@ -2809,6 +2842,8 @@ mongoc_client_set_apm_callbacks (mongoc_client_t *client, mongoc_apm_callbacks_t *callbacks, void *context) { + BSON_ASSERT_PARAM (client); + if (!client->topology->single_threaded) { MONGOC_ERROR ("Cannot set callbacks on a pooled client, use " "mongoc_client_pool_set_apm_callbacks"); @@ -2822,6 +2857,8 @@ mongoc_server_description_t * mongoc_client_get_server_description (mongoc_client_t *client, uint32_t server_id) { + BSON_ASSERT_PARAM (client); + mongoc_server_description_t *ret; mc_shared_tpld td = mc_tpld_take_ref (client->topology); mongoc_server_description_t const *sd = @@ -2837,6 +2874,8 @@ mongoc_server_description_t ** mongoc_client_get_server_descriptions (const mongoc_client_t *client, size_t *n /* OUT */) { + BSON_ASSERT_PARAM (client); + mc_shared_tpld td = mc_tpld_take_ref (BSON_ASSERT_PTR_INLINE (client)->topology); mongoc_server_description_t **const sds = @@ -2867,6 +2906,8 @@ mongoc_client_select_server (mongoc_client_t *client, const mongoc_read_prefs_t *prefs, bson_error_t *error) { + BSON_ASSERT_PARAM (client); + mongoc_ss_optype_t optype = for_writes ? MONGOC_SS_WRITE : MONGOC_SS_READ; mongoc_server_description_t *sd; @@ -2907,6 +2948,8 @@ mongoc_client_select_server (mongoc_client_t *client, bool mongoc_client_set_error_api (mongoc_client_t *client, int32_t version) { + BSON_ASSERT_PARAM (client); + if (!client->topology->single_threaded) { MONGOC_ERROR ("Cannot set Error API Version on a pooled client, use " "mongoc_client_pool_set_error_api"); @@ -2933,6 +2976,8 @@ mongoc_client_set_error_api (mongoc_client_t *client, int32_t version) bool mongoc_client_set_appname (mongoc_client_t *client, const char *appname) { + BSON_ASSERT_PARAM (client); + if (!client->topology->single_threaded) { MONGOC_ERROR ("Cannot call set_appname on a client from a pool"); return false; @@ -2944,6 +2989,8 @@ mongoc_client_set_appname (mongoc_client_t *client, const char *appname) mongoc_server_session_t * _mongoc_client_pop_server_session (mongoc_client_t *client, bson_error_t *error) { + BSON_ASSERT_PARAM (client); + return _mongoc_topology_pop_server_session (client->topology, error); } @@ -2973,6 +3020,7 @@ _mongoc_client_lookup_session (const mongoc_client_t *client, bson_error_t *error /* OUT */) { ENTRY; + BSON_ASSERT_PARAM (client); *cs = mongoc_set_get (client->client_sessions, client_session_id); @@ -2992,6 +3040,8 @@ void _mongoc_client_unregister_session (mongoc_client_t *client, mongoc_client_session_t *session) { + BSON_ASSERT_PARAM (client); + mongoc_set_rm (client->client_sessions, session->client_session_id); } @@ -2999,6 +3049,8 @@ void _mongoc_client_push_server_session (mongoc_client_t *client, mongoc_server_session_t *server_session) { + BSON_ASSERT_PARAM (client); + _mongoc_topology_push_server_session (client->topology, server_session); } @@ -3029,10 +3081,17 @@ _mongoc_client_end_sessions (mongoc_client_t *client) mongoc_cluster_t *cluster = &client->cluster; bool r; + BSON_ASSERT_PARAM (client); + while (!mongoc_server_session_pool_is_empty (t->session_pool)) { prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED); - server_id = mongoc_topology_select_server_id ( - t, MONGOC_SS_READ, prefs, NULL /* chosen read mode */, &error); + server_id = + mongoc_topology_select_server_id (t, + MONGOC_SS_READ, + prefs, + NULL /* chosen read mode */, + NULL /* deprioritized servers */, + &error); mongoc_read_prefs_destroy (prefs); if (!server_id) { @@ -3088,7 +3147,7 @@ _mongoc_client_end_sessions (mongoc_client_t *client) void mongoc_client_reset (mongoc_client_t *client) { - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); client->generation++; @@ -3119,6 +3178,8 @@ mongoc_client_enable_auto_encryption (mongoc_client_t *client, mongoc_auto_encryption_opts_t *opts, bson_error_t *error) { + BSON_ASSERT_PARAM (client); + if (!client->topology->single_threaded) { bson_set_error (error, MONGOC_ERROR_CLIENT, @@ -3169,6 +3230,7 @@ mongoc_client_get_handshake_description (mongoc_client_t *client, mongoc_server_stream_t *server_stream; mongoc_server_description_t *sd; + BSON_ASSERT_PARAM (client); BSON_UNUSED (opts); server_stream = mongoc_cluster_stream_for_server (&client->cluster, @@ -3189,5 +3251,15 @@ mongoc_client_get_handshake_description (mongoc_client_t *client, bool mongoc_client_uses_server_api (const mongoc_client_t *client) { + BSON_ASSERT_PARAM (client); + return mongoc_topology_uses_server_api (client->topology); } + +bool +mongoc_client_uses_loadbalanced (const mongoc_client_t *client) +{ + BSON_ASSERT_PARAM (client); + + return mongoc_topology_uses_loadbalanced (client->topology); +} diff --git a/src/mongoc/mongoc-cluster-aws-private.h b/src/mongoc/mongoc-cluster-aws-private.h index 3b49cb0e..1989ae22 100644 --- a/src/mongoc/mongoc-cluster-aws-private.h +++ b/src/mongoc/mongoc-cluster-aws-private.h @@ -20,7 +20,9 @@ #define MONGOC_CLUSTER_AWS_PRIVATE_H #include "bson/bson.h" +#include "mcd-time.h" #include "mongoc/mongoc-cluster-private.h" +#include "common-thread-private.h" // bson_mutex_t bool _mongoc_cluster_auth_node_aws (mongoc_cluster_t *cluster, @@ -29,24 +31,110 @@ _mongoc_cluster_auth_node_aws (mongoc_cluster_t *cluster, bson_error_t *error); /* The following are declared in the private header for testing. It is only used - * in test-mongoc-aws.c and mongoc-cluster.aws.c */ + * in test-mongoc-aws.c, mongoc-cluster-aws.c, and test-awsauth.c */ typedef struct { char *access_key_id; char *secret_access_key; char *session_token; + // expiration is the time when these credentials expire. + // If expiration.set is false, the credentials do not have a known + // expiration. + struct { + mcd_timer value; + bool set; + } expiration; } _mongoc_aws_credentials_t; +#define MONGOC_AWS_CREDENTIALS_INIT \ + (_mongoc_aws_credentials_t) \ + { \ + .access_key_id = NULL, .secret_access_key = NULL, .session_token = NULL, \ + .expiration = {.value = {.expire_at = {0}}, .set = false}, \ + } + +#define MONGOC_AWS_CREDENTIALS_EXPIRATION_WINDOW_MS 60 * 5 * 1000 + +// _mongoc_aws_credentials_cache_t is a thread-safe global cache of AWS +// credentials. +typedef struct { + struct { + _mongoc_aws_credentials_t value; + bool set; + } cached; + bson_mutex_t mutex; // guards cached. +} _mongoc_aws_credentials_cache_t; + +extern _mongoc_aws_credentials_cache_t mongoc_aws_credentials_cache; + +// _mongoc_aws_credentials_cache_init initializes the global +// `mongoc_aws_credentials_cache. It is expected to be called by mongoc_init. +void +_mongoc_aws_credentials_cache_init (void); + +// _mongoc_aws_credentials_cache_lock exclusively locks the cache. +void +_mongoc_aws_credentials_cache_lock (void); + +// _mongoc_aws_credentials_cache_unlock unlocks the cache. +void +_mongoc_aws_credentials_cache_unlock (void); + +// _mongoc_aws_credentials_cache_put_nolock is a non-locking variant of +// _mongoc_aws_credentials_cache_put. +void +_mongoc_aws_credentials_cache_put_nolock ( + const _mongoc_aws_credentials_t *creds); + +// _mongoc_aws_credentials_cache_put adds credentials into the global cache. +void +_mongoc_aws_credentials_cache_put (const _mongoc_aws_credentials_t *creds); + +// _mongoc_aws_credentials_cache_get_nolock is a non-locking variant of +// _mongoc_aws_credentials_cache_get. +bool +_mongoc_aws_credentials_cache_get_nolock (_mongoc_aws_credentials_t *creds); + +// _mongoc_aws_credentials_cache_get returns true if cached credentials were +// retrieved. +// The passed `creds` is expected to be initialized with +// MONGOC_AWS_CREDENTIALS_INIT. Returns true if there are valid cached +// credentials. Retrieved credentials are copied to `creds`. Callers are +// expected to call +// `_mongoc_aws_credentials_cleanup` on `creds`. +// Returns false and zeroes `creds` if there are no valid cached credentials. +bool +_mongoc_aws_credentials_cache_get (_mongoc_aws_credentials_t *creds); + +// _mongoc_aws_credentials_cache_clear_nolock is the non-locking variant of +// _mongoc_aws_credentials_cache_clear +void +_mongoc_aws_credentials_cache_clear_nolock (void); + +// _mongoc_aws_credentials_cache_clear clears credentials in the global cache +void +_mongoc_aws_credentials_cache_clear (void); + +// _mongoc_aws_credentials_cache_cleanup frees data for the global cache. +// It is expected to be called by mongoc_cleanup. +void +_mongoc_aws_credentials_cache_cleanup (void); + + bool _mongoc_aws_credentials_obtain (mongoc_uri_t *uri, _mongoc_aws_credentials_t *creds, bson_error_t *error); +void +_mongoc_aws_credentials_copy_to (const _mongoc_aws_credentials_t *src, + _mongoc_aws_credentials_t *dst); + void _mongoc_aws_credentials_cleanup (_mongoc_aws_credentials_t *creds); bool _mongoc_validate_and_derive_region (char *sts_fqdn, - uint32_t sts_fqdn_len, + size_t sts_fqdn_len, char **region, bson_error_t *error); diff --git a/src/mongoc/mongoc-cluster-aws.c b/src/mongoc/mongoc-cluster-aws.c index 55cc2fe1..9455e300 100644 --- a/src/mongoc/mongoc-cluster-aws.c +++ b/src/mongoc/mongoc-cluster-aws.c @@ -17,6 +17,7 @@ /* All interaction with kms_message is limited to this file. */ #include "common-b64-private.h" +#include "mcd-time.h" #include "mongoc-cluster-aws-private.h" #include "mongoc-client-private.h" #include "mongoc-host-list-private.h" @@ -26,6 +27,8 @@ #include "mongoc-uri-private.h" #include "mongoc-util-private.h" #include "mongoc-http-private.h" +#include "mongoc-rand-private.h" +#include "mongoc-ssl-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "aws_auth" @@ -134,7 +137,8 @@ _sasl_reply_parse_payload_as_bson (const bson_t *reply, * credentials. */ static bool -_send_http_request (const char *ip, +_send_http_request (bool use_tls, + const char *ip, int port, const char *method, const char *path, @@ -147,6 +151,7 @@ _send_http_request (const char *ip, mongoc_http_response_t res; const int socket_timeout_ms = 10000; bool ret; + mongoc_ssl_opt_t ssl_opt = {0}; *http_response_body = NULL; *http_response_headers = NULL; @@ -158,10 +163,14 @@ _send_http_request (const char *ip, req.method = method; req.path = path; req.extra_headers = headers; + if (use_tls) { + _mongoc_ssl_opts_copy_to ( + mongoc_ssl_opt_get_default (), &ssl_opt, true /* copy_internal */); + } ret = _mongoc_http_send (&req, socket_timeout_ms, - false /* use_tls */, - NULL /* ssl_opts */, + use_tls /* use_tls */, + use_tls ? &ssl_opt : NULL, &res, error); @@ -172,6 +181,7 @@ _send_http_request (const char *ip, } _mongoc_http_response_cleanup (&res); + _mongoc_ssl_opts_cleanup (&ssl_opt, true); return ret; } @@ -296,6 +306,107 @@ _obtain_creds_from_env (_mongoc_aws_credentials_t *creds, bson_error_t *error) return ret; } +// expiration_ms_to_timer converts milliseconds since Unix Epoch into the +// mcd_timer `expiration_timer`. +static bool +expiration_ms_to_timer (int64_t expiration_ms, + mcd_timer *expiration_timer, + bson_error_t *error) +{ + bool ret = false; + + // get current time in milliseconds since Unix Epoch. + int64_t now_ms; + { + struct timeval now; + if (0 != bson_gettimeofday (&now)) { + AUTH_ERROR_AND_FAIL ("bson_gettimeofday returned failure. Unable to " + "determine expiration."); + } else { + now_ms = (1000 * now.tv_sec) + (now.tv_usec / 1000); + } + } + + *expiration_timer = mcd_timer_expire_after (mcd_milliseconds ( + expiration_ms - now_ms - MONGOC_AWS_CREDENTIALS_EXPIRATION_WINDOW_MS)); + ret = true; +fail: + return ret; +} + +// expiration_iso8601_to_timer parses the "Expiration" string value returned +// from an ECS or EC2 response. "Expiration" is expected to be an ISO-8601 +// string. Example: "2023-02-07T20:04:27Z". On success, `expiration_timer` is +// set to the expiration time. +static bool +expiration_iso8601_to_timer (const char *expiration_str, + mcd_timer *expiration_timer, + bson_error_t *error) +{ + bool ret = false; + + // get expiration time in milliseconds since Unix Epoch. + int64_t expiration_ms; + { + bson_error_t json_err; + bson_t date_doc; + bson_iter_t date_iter; + char *date_doc_str; + // libbson has private API `_bson_iso8601_date_parse` to parse ISO-8601 + // strings. The private API is inaccessible to libmongoc. + // Create a temporary bson document with a $date to parse. + date_doc_str = bson_strdup_printf ( + "{\"Expiration\" : {\"$date\" : \"%s\"}}", expiration_str); + + if (!bson_init_from_json (&date_doc, date_doc_str, -1, &json_err)) { + bson_free (date_doc_str); + AUTH_ERROR_AND_FAIL ("failed to parse Expiration: %s", + json_err.message); + } + BSON_ASSERT (bson_iter_init_find (&date_iter, &date_doc, "Expiration")); + expiration_ms = bson_iter_date_time (&date_iter); + bson_free (date_doc_str); + bson_destroy (&date_doc); + } + + if (!expiration_ms_to_timer (expiration_ms, expiration_timer, error)) { + goto fail; + } + ret = true; +fail: + return ret; +} + +// generate_AWS_ROLE_SESSION_NAME generates a 16 byte hex string (32 characters) +// to use as the AWS_ROLE_SESSION_NAME. +static char * +generate_AWS_ROLE_SESSION_NAME (bson_error_t *error) +{ +#define NUM_BYTES 16 + bool ok = false; + uint8_t data[NUM_BYTES]; + char *out = bson_malloc (NUM_BYTES * 2 + 1); + if (!_mongoc_rand_bytes (data, NUM_BYTES)) { + AUTH_ERROR_AND_FAIL ( + "unable to generate random bytes for AWS_ROLE_SESSION_NAME"); + } + + size_t i; + for (i = 0; i < NUM_BYTES; i++) { + bson_snprintf (out + (2 * i), 3, "%02x", data[i]); + } + out[NUM_BYTES * 2] = '\0'; + + ok = true; +fail: + if (!ok) { + bson_free (out); + out = NULL; + } + return out; +#undef NUM_BYTES +} + static bool _obtain_creds_from_ecs (_mongoc_aws_credentials_t *creds, bson_error_t *error) { @@ -316,7 +427,8 @@ _obtain_creds_from_ecs (_mongoc_aws_credentials_t *creds, bson_error_t *error) return true; } - if (!_send_http_request ("169.254.170.2", + if (!_send_http_request (false /* use_tls */, + "169.254.170.2", 80, "GET", relative_ecs_uri, @@ -350,6 +462,15 @@ _obtain_creds_from_ecs (_mongoc_aws_credentials_t *creds, bson_error_t *error) ecs_session_token = bson_iter_utf8 (&iter, NULL); } + if (bson_iter_init_find_case (&iter, response_json, "Expiration") && + BSON_ITER_HOLDS_UTF8 (&iter)) { + if (!expiration_iso8601_to_timer ( + bson_iter_utf8 (&iter, NULL), &creds->expiration.value, error)) { + goto fail; + } + creds->expiration.set = true; + } + if (!_validate_and_set_creds (ecs_access_key_id, ecs_secret_access_key, ecs_session_token, @@ -358,7 +479,6 @@ _obtain_creds_from_ecs (_mongoc_aws_credentials_t *creds, bson_error_t *error) goto fail; } - ret = true; fail: bson_destroy (response_json); @@ -368,6 +488,216 @@ _obtain_creds_from_ecs (_mongoc_aws_credentials_t *creds, bson_error_t *error) return ret; } +static bool +_obtain_creds_from_assumerolewithwebidentity (_mongoc_aws_credentials_t *creds, + bson_error_t *error) +{ + bool ret = false; + char *http_response_headers = NULL; + char *http_response_body = NULL; + char *aws_web_identity_token_file = NULL; + char *aws_role_arn = NULL; + char *aws_role_session_name = NULL; + bson_t *response_bson = NULL; + bson_iter_t iter; + const char *access_key_id = NULL; + const char *secret_access_key = NULL; + const char *session_token = NULL; + bson_error_t http_error; + mongoc_stream_t *fstream = NULL; + bson_string_t *token_file_contents = NULL; + char *path_and_query = NULL; + + aws_web_identity_token_file = _mongoc_getenv ("AWS_WEB_IDENTITY_TOKEN_FILE"); + aws_role_arn = _mongoc_getenv ("AWS_ROLE_ARN"); + if (!aws_web_identity_token_file || + strlen (aws_web_identity_token_file) == 0 || !aws_role_arn || + strlen (aws_role_arn) == 0) { + bson_free (aws_role_arn); + bson_free (aws_web_identity_token_file); + // Not an error. May need to obtain credentials another way. + return true; + } + + aws_role_session_name = _mongoc_getenv ("AWS_ROLE_SESSION_NAME"); + if (!aws_role_session_name) { + aws_role_session_name = generate_AWS_ROLE_SESSION_NAME (error); + if (!aws_role_session_name) { + goto fail; + } + } + + // Read the contents of the file given by ``AWS_WEB_IDENTITY_TOKEN_FILE``. + { + fstream = mongoc_stream_file_new_for_path ( + aws_web_identity_token_file, O_RDONLY, 0); + if (!fstream) { + AUTH_ERROR_AND_FAIL ( + "failed to open AWS_WEB_IDENTITY_TOKEN_FILE: %s. Reason: %s", + aws_web_identity_token_file, + strerror (errno)); + } + + token_file_contents = bson_string_new (NULL); + + for (;;) { + char buf[128]; + ssize_t got = mongoc_stream_read ( + fstream, + buf, + sizeof (buf) - 1 /* leave space for null terminator */, + 0 /* min_bytes */, + 0 /* timeout_msec. Unused for file stream. */); + + if (got > 0) { + // add null terminator. + buf[got] = '\0'; + bson_string_append (token_file_contents, (const char *) buf); + } else if (got == 0) { + // EOF. + break; + } else { + AUTH_ERROR_AND_FAIL ( + "failed to read AWS_WEB_IDENTITY_TOKEN_FILE: %s. Reason: %s", + aws_web_identity_token_file, + strerror (errno)); + } + } + } + + path_and_query = + bson_strdup_printf ("/?Action=AssumeRoleWithWebIdentity" + "&RoleSessionName=%s" + "&RoleArn=%s" + "&WebIdentityToken=%s&Version=2011-06-15", + aws_role_session_name, + aws_role_arn, + token_file_contents->str); + + // send an HTTP request to sts.amazonaws.com. + if (!_send_http_request (true /* use_tls */, + "sts.amazonaws.com", + 443, + "POST", + path_and_query, + "Accept: application/json\r\n", + &http_response_body, + &http_response_headers, + &http_error)) { + AUTH_ERROR_AND_FAIL ("failed to contact sts.amazonaws.com: %s", + http_error.message); + } + + response_bson = bson_new_from_json ( + (const uint8_t *) http_response_body, strlen (http_response_body), error); + if (!response_bson) { + AUTH_ERROR_AND_FAIL ("invalid JSON in response from sts.amazonaws.com. " + "Response headers: %s", + http_response_headers); + } + + if (!bson_iter_init (&iter, response_bson)) { + AUTH_ERROR_AND_FAIL ("failed to initialize BSON iterator to response: %s", + http_response_body); + } + + // If the response contains "Error", return only the "Error" document. + // Do not include http_response_body in subsequent errors to limit risk of + // including credentials in error messages. + bson_iter_t Error_iter; + if (bson_iter_init_find (&Error_iter, response_bson, "Error")) { + bson_t Error_bson; + if (!_mongoc_iter_document_as_bson (&Error_iter, &Error_bson, error)) { + goto fail; + } + char *Error_json = bson_as_json (&Error_bson, NULL); + bson_set_error ( + error, + MONGOC_ERROR_CLIENT, + MONGOC_ERROR_CLIENT_AUTHENTICATE, + "Response to AssumeRoleWithWebIdentity contains 'Error': %s", + Error_json); + bson_free (Error_json); + goto fail; + } + + bson_iter_t Credentials_iter; + if (!bson_iter_find_descendant ( + &iter, + "AssumeRoleWithWebIdentityResponse.AssumeRoleWithWebIdentityResult." + "Credentials", + &iter)) { + AUTH_ERROR_AND_FAIL ( + "did not find " + "AssumeRoleWithWebIdentityResponse.AssumeRoleWithWebIdentityResult." + "Credentials in response from sts.amazonaws.com."); + } + + if (!bson_iter_recurse (&iter, &Credentials_iter)) { + AUTH_ERROR_AND_FAIL ( + "Unable to recurse in Credentials in response from sts.amazonaws.com"); + } + + iter = Credentials_iter; + if (bson_iter_find (&iter, "AccessKeyId") && BSON_ITER_HOLDS_UTF8 (&iter)) { + access_key_id = bson_iter_utf8 (&iter, NULL); + } else { + AUTH_ERROR_AND_FAIL ( + "did not find AccessKeyId in response from sts.amazonaws.com"); + } + + iter = Credentials_iter; + if (bson_iter_find (&iter, "SecretAccessKey") && + BSON_ITER_HOLDS_UTF8 (&iter)) { + secret_access_key = bson_iter_utf8 (&iter, NULL); + } else { + AUTH_ERROR_AND_FAIL ( + "did not find SecretAccessKey in response from sts.amazonaws.com"); + } + + iter = Credentials_iter; + if (bson_iter_find (&iter, "SessionToken") && BSON_ITER_HOLDS_UTF8 (&iter)) { + session_token = bson_iter_utf8 (&iter, NULL); + } else { + AUTH_ERROR_AND_FAIL ( + "did not find SessionToken in response from sts.amazonaws.com"); + } + + iter = Credentials_iter; + if (bson_iter_find (&iter, "Expiration") && BSON_ITER_HOLDS_DOUBLE (&iter)) { + // "Expiration" is returned as a double representing the number of seconds + // since Unix Epoch. This differs from the ISO-8601 string returned in EC2 + // and ECS responses. + int64_t expiration_ms = (int64_t) (1000.0 * bson_iter_double (&iter)); + if (!expiration_ms_to_timer ( + expiration_ms, &creds->expiration.value, error)) { + goto fail; + } + creds->expiration.set = true; + } else { + AUTH_ERROR_AND_FAIL ( + "did not find Expiration in response from sts.amazonaws.com"); + } + + if (!_validate_and_set_creds ( + access_key_id, secret_access_key, session_token, creds, error)) { + goto fail; + } + + ret = true; +fail: + bson_free (path_and_query); + bson_destroy (response_bson); + bson_free (http_response_headers); + bson_free (http_response_body); + bson_string_free (token_file_contents, true /* free segment */); + mongoc_stream_destroy (fstream); + bson_free (aws_role_session_name); + bson_free (aws_role_arn); + bson_free (aws_web_identity_token_file); + return ret; +} + static bool _obtain_creds_from_ec2 (_mongoc_aws_credentials_t *creds, bson_error_t *error) { @@ -388,7 +718,8 @@ _obtain_creds_from_ec2 (_mongoc_aws_credentials_t *creds, bson_error_t *error) const char *ip = "169.254.169.254"; /* Get the token. */ - if (!_send_http_request (ip, + if (!_send_http_request (false /* use_tls */, + ip, 80, "PUT", "/latest/api/token", @@ -412,7 +743,8 @@ _obtain_creds_from_ec2 (_mongoc_aws_credentials_t *creds, bson_error_t *error) bson_strdup_printf ("X-aws-ec2-metadata-token: %s\r\n", token); /* Get the role name. */ - if (!_send_http_request (ip, + if (!_send_http_request (false /* use_tls */, + ip, 80, "GET", "/latest/meta-data/iam/security-credentials/", @@ -435,7 +767,8 @@ _obtain_creds_from_ec2 (_mongoc_aws_credentials_t *creds, bson_error_t *error) "/latest/meta-data/iam/security-credentials/%s", role_name); bson_free (http_response_headers); http_response_headers = NULL; - if (!_send_http_request (ip, + if (!_send_http_request (false /* use_tls */, + ip, 80, "GET", path_with_role, @@ -469,6 +802,15 @@ _obtain_creds_from_ec2 (_mongoc_aws_credentials_t *creds, bson_error_t *error) ec2_session_token = bson_iter_utf8 (&iter, NULL); } + if (bson_iter_init_find_case (&iter, response_json, "Expiration") && + BSON_ITER_HOLDS_UTF8 (&iter)) { + if (!expiration_iso8601_to_timer ( + bson_iter_utf8 (&iter, NULL), &creds->expiration.value, error)) { + goto fail; + } + creds->expiration.set = true; + } + if (!_validate_and_set_creds (ec2_access_key_id, ec2_secret_access_key, ec2_session_token, @@ -509,9 +851,16 @@ _mongoc_aws_credentials_obtain (mongoc_uri_t *uri, { bool ret = false; - creds->access_key_id = NULL; - creds->secret_access_key = NULL; - creds->session_token = NULL; + BSON_ASSERT_PARAM (creds); + *creds = MONGOC_AWS_CREDENTIALS_INIT; + + // Check cache before enviroment variables. This is required by the + // specification: "Even if the environment variables are present in + // subsequent authorization attempts, the driver MUST use the cached + // credentials" + if (_mongoc_aws_credentials_cache_get (creds)) { + goto succeed; + } if (uri) { TRACE ("%s", "checking URI for credentials"); @@ -531,20 +880,61 @@ _mongoc_aws_credentials_obtain (mongoc_uri_t *uri, goto succeed; } - TRACE ("%s", "checking ECS metadata for credentials"); - if (!_obtain_creds_from_ecs (creds, error)) { - goto fail; - } - if (!_creds_empty (creds)) { - goto succeed; - } + // Try to fetch credentials from cacheable sources: + // AssumeRoleWithWebIdentity, ECS or EC2. Lock the cache to prevent duplicate + // requests. + { + _mongoc_aws_credentials_cache_lock (); - TRACE ("%s", "checking EC2 metadata for credentials"); - if (!_obtain_creds_from_ec2 (creds, error)) { - goto fail; - } - if (!_creds_empty (creds)) { - goto succeed; + // Check again if credentials have been cached. + if (_mongoc_aws_credentials_cache_get_nolock (creds)) { + _mongoc_aws_credentials_cache_unlock (); + goto succeed; + } + + TRACE ("%s", "checking AssumeRoleWithWebIdentity for credentials"); + if (!_obtain_creds_from_assumerolewithwebidentity (creds, error)) { + _mongoc_aws_credentials_cache_unlock (); + goto fail; + } + if (!_creds_empty (creds)) { + if (creds->expiration.set) { + // Only try to cache credentials if an expiration time is included. + _mongoc_aws_credentials_cache_put_nolock (creds); + } + _mongoc_aws_credentials_cache_unlock (); + goto succeed; + } + + TRACE ("%s", "checking ECS metadata for credentials"); + if (!_obtain_creds_from_ecs (creds, error)) { + _mongoc_aws_credentials_cache_unlock (); + goto fail; + } + if (!_creds_empty (creds)) { + if (creds->expiration.set) { + // Only try to cache credentials if an expiration time is included. + _mongoc_aws_credentials_cache_put_nolock (creds); + } + _mongoc_aws_credentials_cache_unlock (); + goto succeed; + } + + TRACE ("%s", "checking EC2 metadata for credentials"); + if (!_obtain_creds_from_ec2 (creds, error)) { + _mongoc_aws_credentials_cache_unlock (); + goto fail; + } + if (!_creds_empty (creds)) { + if (creds->expiration.set) { + // Only try to cache credentials if an expiration time is included. + _mongoc_aws_credentials_cache_put_nolock (creds); + } + _mongoc_aws_credentials_cache_unlock (); + goto succeed; + } + + _mongoc_aws_credentials_cache_unlock (); } AUTH_ERROR_AND_FAIL ("unable to get credentials\n"); @@ -555,14 +945,6 @@ _mongoc_aws_credentials_obtain (mongoc_uri_t *uri, return ret; } -void -_mongoc_aws_credentials_cleanup (_mongoc_aws_credentials_t *creds) -{ - bson_free (creds->access_key_id); - bson_free (creds->secret_access_key); - bson_free (creds->session_token); -} - /* * Validate the STS host returned by the server and derive the region. * @@ -572,7 +954,7 @@ _mongoc_aws_credentials_cleanup (_mongoc_aws_credentials_t *creds) */ bool _mongoc_validate_and_derive_region (char *sts_fqdn, - uint32_t sts_fqdn_len, + size_t sts_fqdn_len, char **region, bson_error_t *error) { @@ -586,11 +968,11 @@ _mongoc_validate_and_derive_region (char *sts_fqdn, /* Drivers must also validate that the host is greater than 0 and less than * or equal to 255 bytes per RFC 1035 */ - if (sts_fqdn_len == 0) { + if (sts_fqdn_len == 0u) { AUTH_ERROR_AND_FAIL ("invalid STS host: empty"); } - if (sts_fqdn_len > 255) { + if (sts_fqdn_len > 255u) { AUTH_ERROR_AND_FAIL ("invalid STS host: too large"); } @@ -860,7 +1242,7 @@ _client_second (mongoc_cluster_t *cluster, AUTH_ERROR_AND_FAIL ("Failed to parse server nonce"); } - if (!kms_request_append_payload (request, body, -1)) { + if (!kms_request_append_payload (request, body, strlen(body))) { AUTH_ERROR_AND_FAIL ("Failed to append payload"); } @@ -920,7 +1302,7 @@ _client_second (mongoc_cluster_t *cluster, bson_destroy (&client_command); bson_destroy (&server_reply); kms_request_destroy (request); - free (signature); + bson_free (signature); bson_free (server_nonce_str); return ret; } @@ -936,7 +1318,7 @@ _mongoc_cluster_auth_node_aws (mongoc_cluster_t *cluster, char *sts_fqdn = NULL; char *region = NULL; int conv_id = 0; - _mongoc_aws_credentials_t creds = {0}; + _mongoc_aws_credentials_t creds = MONGOC_AWS_CREDENTIALS_INIT; if (!_mongoc_aws_credentials_obtain (cluster->client->uri, &creds, error)) { goto fail; @@ -967,6 +1349,9 @@ _mongoc_cluster_auth_node_aws (mongoc_cluster_t *cluster, ret = true; fail: + if (!ret) { + _mongoc_aws_credentials_cache_clear (); + } _mongoc_aws_credentials_cleanup (&creds); bson_free (sts_fqdn); bson_free (region); @@ -999,15 +1384,9 @@ _mongoc_aws_credentials_obtain (mongoc_uri_t *uri, return false; } -void -_mongoc_aws_credentials_cleanup (_mongoc_aws_credentials_t *creds) -{ - return; -} - bool _mongoc_validate_and_derive_region (char *sts_fqdn, - uint32_t sts_fqdn_len, + size_t sts_fqdn_len, char **region, bson_error_t *error) { @@ -1018,3 +1397,140 @@ _mongoc_validate_and_derive_region (char *sts_fqdn, } #endif /* MONGOC_ENABLE_MONGODB_AWS_AUTH */ + +void +_mongoc_aws_credentials_cleanup (_mongoc_aws_credentials_t *creds) +{ + bson_free (creds->access_key_id); + bson_free (creds->secret_access_key); + bson_free (creds->session_token); +} + +void +_mongoc_aws_credentials_copy_to (const _mongoc_aws_credentials_t *src, + _mongoc_aws_credentials_t *dst) +{ + BSON_ASSERT_PARAM (src); + BSON_ASSERT_PARAM (dst); + + dst->access_key_id = bson_strdup (src->access_key_id); + dst->secret_access_key = bson_strdup (src->secret_access_key); + dst->session_token = bson_strdup (src->session_token); + dst->expiration = src->expiration; +} + +_mongoc_aws_credentials_cache_t mongoc_aws_credentials_cache; + +void +_mongoc_aws_credentials_cache_init (void) +{ + _mongoc_aws_credentials_cache_t *cache = &mongoc_aws_credentials_cache; + bson_mutex_init (&cache->mutex); +} + +static bool +check_expired (const _mongoc_aws_credentials_t *creds) +{ + if (!creds->expiration.set) { + return true; + } + return mcd_get_milliseconds ( + mcd_timer_remaining (creds->expiration.value)) == 0; +} + +void +_mongoc_aws_credentials_cache_lock (void) +{ + _mongoc_aws_credentials_cache_t *cache = &mongoc_aws_credentials_cache; + bson_mutex_lock (&cache->mutex); +} + +void +_mongoc_aws_credentials_cache_unlock (void) +{ + _mongoc_aws_credentials_cache_t *cache = &mongoc_aws_credentials_cache; + bson_mutex_unlock (&cache->mutex); +} + +void +_mongoc_aws_credentials_cache_put_nolock ( + const _mongoc_aws_credentials_t *creds) +{ + _mongoc_aws_credentials_cache_t *cache = &mongoc_aws_credentials_cache; + BSON_ASSERT_PARAM (creds); + + if (check_expired (creds)) { + // Do not add expired credentials. + return; + } + _mongoc_aws_credentials_cache_clear_nolock (); + _mongoc_aws_credentials_copy_to (creds, &cache->cached.value); + cache->cached.set = true; +} + +void +_mongoc_aws_credentials_cache_put (const _mongoc_aws_credentials_t *creds) +{ + _mongoc_aws_credentials_cache_lock (); + _mongoc_aws_credentials_cache_put_nolock (creds); + _mongoc_aws_credentials_cache_unlock (); +} + +bool +_mongoc_aws_credentials_cache_get_nolock (_mongoc_aws_credentials_t *creds) +{ + _mongoc_aws_credentials_cache_t *cache = &mongoc_aws_credentials_cache; + BSON_ASSERT_PARAM (creds); + bool found_valid = false; + bool expired = false; + if (cache->cached.set) { + expired = check_expired (&cache->cached.value); + if (!expired) { + found_valid = true; + _mongoc_aws_credentials_copy_to (&cache->cached.value, creds); + } + } + if (expired) { + _mongoc_aws_credentials_cache_clear_nolock (); + return false; + } + return found_valid; +} + +bool +_mongoc_aws_credentials_cache_get (_mongoc_aws_credentials_t *creds) +{ + _mongoc_aws_credentials_cache_lock (); + bool got = _mongoc_aws_credentials_cache_get_nolock (creds); + _mongoc_aws_credentials_cache_unlock (); + return got; +} + +void +_mongoc_aws_credentials_cache_clear_nolock (void) +{ + _mongoc_aws_credentials_cache_t *cache = &mongoc_aws_credentials_cache; + + if (cache->cached.set) { + _mongoc_aws_credentials_cleanup (&cache->cached.value); + } + cache->cached.set = false; +} + +void +_mongoc_aws_credentials_cache_clear (void) +{ + _mongoc_aws_credentials_cache_lock (); + _mongoc_aws_credentials_cache_clear_nolock (); + _mongoc_aws_credentials_cache_unlock (); +} + +void +_mongoc_aws_credentials_cache_cleanup (void) +{ + _mongoc_aws_credentials_cache_t *cache = &mongoc_aws_credentials_cache; + if (cache->cached.set) { + _mongoc_aws_credentials_cleanup (&cache->cached.value); + } + bson_mutex_destroy (&cache->mutex); +} diff --git a/src/mongoc/mongoc-cluster-private.h b/src/mongoc/mongoc-cluster-private.h index e8452231..7af22850 100644 --- a/src/mongoc/mongoc-cluster-private.h +++ b/src/mongoc/mongoc-cluster-private.h @@ -21,6 +21,7 @@ #include +#include "mcd-rpc.h" #include "mongoc-array-private.h" #include "mongoc-buffer-private.h" #include "mongoc-config.h" @@ -37,6 +38,7 @@ #include "mongoc-scram-private.h" #include "mongoc-cmd-private.h" #include "mongoc-crypto-private.h" +#include "mongoc-deprioritized-servers-private.h" BSON_BEGIN_DECLS @@ -51,9 +53,9 @@ typedef struct _mongoc_cluster_node_t { typedef struct _mongoc_cluster_t { int64_t operation_id; - uint32_t request_id; - uint32_t sockettimeoutms; - uint32_t socketcheckintervalms; + int32_t request_id; + int32_t sockettimeoutms; + int32_t socketcheckintervalms; mongoc_uri_t *uri; unsigned requires_auth : 1; @@ -61,8 +63,6 @@ typedef struct _mongoc_cluster_t { mongoc_set_t *nodes; mongoc_array_t iov; - - mongoc_scram_cache_t *scram_cache; } mongoc_cluster_t; @@ -95,13 +95,13 @@ mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id); bool mongoc_cluster_legacy_rpc_sendv_to_server ( mongoc_cluster_t *cluster, - mongoc_rpc_t *rpcs, + mcd_rpc_message *rpc, mongoc_server_stream_t *server_stream, bson_error_t *error); bool mongoc_cluster_try_recv (mongoc_cluster_t *cluster, - mongoc_rpc_t *rpc, + mcd_rpc_message *rpc, mongoc_buffer_t *buffer, mongoc_server_stream_t *server_stream, bson_error_t *error); @@ -122,8 +122,8 @@ mongoc_server_stream_t * mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster, const mongoc_read_prefs_t *read_prefs, mongoc_client_session_t *cs, + const mongoc_deprioritized_servers_t *ds, bson_t *reply, - bool is_aggr_with_write, bson_error_t *error); /** @@ -140,9 +140,30 @@ mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster, mongoc_server_stream_t * mongoc_cluster_stream_for_writes (mongoc_cluster_t *cluster, mongoc_client_session_t *cs, + const mongoc_deprioritized_servers_t *ds, bson_t *reply, bson_error_t *error); +/** + * @brief Obtain a server stream appropriate for aggregate operations with + * writes on the cluster. + * + * Returns a new stream (that must be freed) or NULL and sets an error via + * `error`. + * + * @note The returned stream must be released via + * `mongoc_server_stream_cleanup`. + * + * @note May add nodes and/or update the cluster's topology. + */ +mongoc_server_stream_t * +mongoc_cluster_stream_for_aggr_with_write ( + mongoc_cluster_t *cluster, + const mongoc_read_prefs_t *read_prefs, + mongoc_client_session_t *cs, + bson_t *reply, + bson_error_t *error); + /** * @brief Obtain a server stream associated with the cluster node associated * with the given server ID. @@ -215,11 +236,16 @@ _mongoc_cluster_get_auth_cmd_x509 (const mongoc_uri_t *uri, bson_t *cmd /* OUT */, bson_error_t *error /* OUT */); -/* Returns true if a versioned server API has been selected, - * otherwise returns false. */ +/* Returns true if a versioned server API has been selected, otherwise returns + * false. */ bool mongoc_cluster_uses_server_api (const mongoc_cluster_t *cluster); +/* Returns true if load balancing mode has been selected, otherwise returns + * false. */ +bool +mongoc_cluster_uses_loadbalanced (const mongoc_cluster_t *cluster); + #ifdef MONGOC_ENABLE_CRYPTO void _mongoc_cluster_init_scram (const mongoc_cluster_t *cluster, @@ -233,6 +259,24 @@ _mongoc_cluster_get_auth_cmd_scram (mongoc_crypto_hash_algorithm_t algo, bson_error_t *error /* OUT */); #endif /* MONGOC_ENABLE_CRYPTO */ +bool +mcd_rpc_message_compress (mcd_rpc_message *rpc, + int32_t compressor_id, + int32_t compression_level, + void **compressed_data, + size_t *compressed_data_len, + bson_error_t *error); + +bool +mcd_rpc_message_decompress (mcd_rpc_message *rpc, + void **data, + size_t *data_len); + +bool +mcd_rpc_message_decompress_if_necessary (mcd_rpc_message *rpc, + void **data, + size_t *data_len); + BSON_END_DECLS diff --git a/src/mongoc/mongoc-cluster-sspi.c b/src/mongoc/mongoc-cluster-sspi.c index 2b2575c9..13cf8c52 100644 --- a/src/mongoc/mongoc-cluster-sspi.c +++ b/src/mongoc/mongoc-cluster-sspi.c @@ -71,7 +71,7 @@ _mongoc_cluster_sspi_new (mongoc_uri_t *uri, service_ascii_len = strlen (service_ascii); /* this is donated to the sspi */ - service = calloc (service_ascii_len + 1, sizeof (WCHAR)); + service = bson_malloc0 ((service_ascii_len + 1) * sizeof (WCHAR)); service_len = MultiByteToWideChar (CP_UTF8, 0, service_ascii, @@ -85,7 +85,7 @@ _mongoc_cluster_sspi_new (mongoc_uri_t *uri, tmp_creds_len = strlen (state->sasl.pass); /* this is donated to the sspi */ - pass = calloc (tmp_creds_len + 1, sizeof (WCHAR)); + pass = bson_malloc0 ((tmp_creds_len + 1) * sizeof (WCHAR)); pass_len = MultiByteToWideChar (CP_UTF8, 0, state->sasl.pass, @@ -99,7 +99,7 @@ _mongoc_cluster_sspi_new (mongoc_uri_t *uri, tmp_creds_len = strlen (state->sasl.user); /* this is donated to the sspi */ - user = calloc (tmp_creds_len + 1, sizeof (WCHAR)); + user = bson_malloc0 ((tmp_creds_len + 1) * sizeof (WCHAR)); user_len = MultiByteToWideChar (CP_UTF8, 0, state->sasl.user, diff --git a/src/mongoc/mongoc-cluster.c b/src/mongoc/mongoc-cluster.c index e99071ad..343528bf 100644 --- a/src/mongoc/mongoc-cluster.c +++ b/src/mongoc/mongoc-cluster.c @@ -19,6 +19,7 @@ #include +#include "mcd-rpc.h" #include "mongoc-cluster-private.h" #include "mongoc-client-private.h" #include "mongoc-client-side-encryption-private.h" @@ -56,6 +57,10 @@ #include "mongoc-cluster-aws-private.h" #include "mongoc-error-private.h" +#include + +#include + #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "cluster" @@ -114,7 +119,6 @@ _handle_not_primary_error (mongoc_cluster_t *cluster, static void _handle_network_error (mongoc_cluster_t *cluster, mongoc_server_stream_t *server_stream, - bool handshake_complete, const bson_error_t *why) { mongoc_topology_t *topology; @@ -133,7 +137,7 @@ _handle_network_error (mongoc_cluster_t *cluster, _mongoc_topology_handle_app_error (topology, server_id, - handshake_complete, + true, // handshake_complete type, NULL, why, @@ -147,19 +151,41 @@ _handle_network_error (mongoc_cluster_t *cluster, } +static int32_t +_int32_from_le (const void *data) +{ + BSON_ASSERT_PARAM (data); + return bson_iter_int32_unsafe (&(bson_iter_t){.raw = data}); +} + + +static int32_t +_compression_level_from_uri (int32_t compressor_id, const mongoc_uri_t *uri) +{ + if (compressor_id == MONGOC_COMPRESSOR_ZLIB_ID) { + return mongoc_uri_get_option_as_int32 ( + uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, -1); + } + + return -1; +} + + size_t _mongoc_cluster_buffer_iovec (mongoc_iovec_t *iov, size_t iovcnt, int skip, char *buffer) { - int n; size_t buffer_offset = 0; int total_iov_len = 0; - int difference = 0; + size_t difference = 0; - for (n = 0; n < iovcnt; n++) { - total_iov_len += iov[n].iov_len; + for (size_t n = 0u; n < iovcnt; n++) { + BSON_ASSERT (bson_in_range_unsigned (int, iov[n].iov_len)); + const int iov_len = (int) iov[n].iov_len; + + total_iov_len += iov_len; if (total_iov_len <= skip) { continue; @@ -168,10 +194,11 @@ _mongoc_cluster_buffer_iovec (mongoc_iovec_t *iov, /* If this iovec starts before the skip, and takes the total count * beyond the skip, we need to figure out the portion of the iovec * we should skip passed */ - if (total_iov_len - iov[n].iov_len < skip) { - difference = skip - (total_iov_len - iov[n].iov_len); + const int remaining = total_iov_len - iov_len; + if (remaining < skip) { + difference = (size_t) (skip - remaining); } else { - difference = 0; + difference = 0u; } memcpy (buffer + buffer_offset, @@ -216,237 +243,257 @@ _bson_error_message_printf (bson_error_t *error, const char *format, ...) RUN_CMD_ERR_DECORATE; \ } while (0) -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_run_command_opquery -- - * - * Internal function to run a command on a given stream. @error and - * @reply are optional out-pointers. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @reply is set and should ALWAYS be released with bson_destroy(). - * On failure, @error is filled out. If this was a network error - * and server_id is nonzero, the cluster disconnects from the server. - * - *-------------------------------------------------------------------------- - */ + +// msgHeader consists of four int32 fields. +static const int32_t message_header_length = 4u * sizeof (int32_t); + static bool -mongoc_cluster_run_command_opquery (mongoc_cluster_t *cluster, - mongoc_cmd_t *cmd, - int32_t compressor_id, - bson_t *reply, - bson_error_t *error) +_mongoc_cluster_run_command_opquery_send (mongoc_cluster_t *cluster, + mongoc_cmd_t *cmd, + int32_t compressor_id, + mcd_rpc_message *rpc, + bson_error_t *error) { - const size_t reply_header_size = sizeof (mongoc_rpc_reply_header_t); - uint8_t reply_header_buf[sizeof (mongoc_rpc_reply_header_t)]; - uint8_t *reply_buf; /* reply body */ - mongoc_rpc_t rpc; /* sent to server */ - bson_t reply_local; - bson_t *reply_ptr; - char *cmd_ns; - uint32_t request_id; - int32_t msg_len; - size_t doc_len; + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT_PARAM (cmd); + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (error); + bool ret = false; - char *output = NULL; - mongoc_stream_t *stream; - ENTRY; + mongoc_stream_t *const stream = cmd->server_stream->stream; + + char *const ns = bson_strdup_printf ("%s.$cmd", cmd->db_name); + const int32_t request_id = ++cluster->request_id; + + // Find, getMore And killCursors Commands Spec: "When sending a find command + // rather than a legacy OP_QUERY find, only the secondaryOk flag is honored." + // For other cursor-typed commands like aggregate, only secondaryOk can be + // set. Clear bits except secondaryOk; leave secondaryOk set only if it is + // already. + const int32_t flags = + (int32_t) cmd->query_flags & MONGOC_OP_QUERY_FLAG_SECONDARY_OK; + + { + int32_t message_length = 0; + + message_length += mcd_rpc_header_set_message_length (rpc, 0); + message_length += mcd_rpc_header_set_request_id (rpc, request_id); + message_length += mcd_rpc_header_set_response_to (rpc, 0); + message_length += mcd_rpc_header_set_op_code (rpc, MONGOC_OP_CODE_QUERY); + + message_length += mcd_rpc_op_query_set_flags (rpc, flags); + message_length += mcd_rpc_op_query_set_full_collection_name (rpc, ns); + message_length += mcd_rpc_op_query_set_number_to_skip (rpc, 0); + message_length += mcd_rpc_op_query_set_number_to_return (rpc, -1); + message_length += + mcd_rpc_op_query_set_query (rpc, bson_get_data (cmd->command)); + + mcd_rpc_message_set_length (rpc, message_length); + } + + size_t num_iovecs = 0u; + mongoc_iovec_t *const iovecs = mcd_rpc_message_to_iovecs (rpc, &num_iovecs); + BSON_ASSERT (iovecs); + + const bool is_compressible = + compressor_id != -1 && IS_NOT_COMMAND (HANDSHAKE_CMD_LEGACY_HELLO) && + IS_NOT_COMMAND ("hello") && IS_NOT_COMMAND ("saslstart") && + IS_NOT_COMMAND ("saslcontinue") && IS_NOT_COMMAND ("getnonce") && + IS_NOT_COMMAND ("authenticate") && IS_NOT_COMMAND ("createuser") && + IS_NOT_COMMAND ("updateuser"); + + void *compressed_data = NULL; + size_t compressed_data_len = 0u; + + if (is_compressible && + !mcd_rpc_message_compress ( + rpc, + compressor_id, + _compression_level_from_uri (compressor_id, cluster->uri), + &compressed_data, + &compressed_data_len, + error)) { + goto done; + } - BSON_ASSERT (cluster); - BSON_ASSERT (cmd); - BSON_ASSERT (cmd->server_stream); + if (cluster->client->in_exhaust) { + bson_set_error (error, + MONGOC_ERROR_CLIENT, + MONGOC_ERROR_CLIENT_IN_EXHAUST, + "a cursor derived from this client is in exhaust"); + goto done; + } - stream = cmd->server_stream->stream; - /* - * setup - */ - reply_ptr = reply ? reply : &reply_local; - bson_init (reply_ptr); + mcd_rpc_message_egress (rpc); + if (!_mongoc_stream_writev_full ( + stream, iovecs, num_iovecs, cluster->sockettimeoutms, error)) { + RUN_CMD_ERR_DECORATE; + _handle_network_error (cluster, cmd->server_stream, error); + goto done; + } - error->code = 0; + ret = true; - /* - * prepare the request - */ +done: + bson_free (compressed_data); + bson_free (iovecs); + bson_free (ns); - _mongoc_array_clear (&cluster->iov); + return ret; +} - cmd_ns = bson_strdup_printf ("%s.$cmd", cmd->db_name); - request_id = ++cluster->request_id; - _mongoc_rpc_prep_command (&rpc, cmd_ns, cmd); - rpc.header.request_id = request_id; +static bool +_mongoc_cluster_run_command_opquery_recv (mongoc_cluster_t *cluster, + mongoc_cmd_t *cmd, + mcd_rpc_message *rpc, + bson_t *reply, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT_PARAM (cmd); + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (reply); + BSON_ASSERT_PARAM (error); - _mongoc_rpc_gather (&rpc, &cluster->iov); - _mongoc_rpc_swab_to_le (&rpc); + bool ret = false; - if (compressor_id != -1 && IS_NOT_COMMAND (HANDSHAKE_CMD_LEGACY_HELLO) && - IS_NOT_COMMAND ("hello") && IS_NOT_COMMAND ("saslstart") && - IS_NOT_COMMAND ("saslcontinue") && IS_NOT_COMMAND ("getnonce") && - IS_NOT_COMMAND ("authenticate") && IS_NOT_COMMAND ("createuser") && - IS_NOT_COMMAND ("updateuser")) { - output = _mongoc_rpc_compress (cluster, compressor_id, &rpc, error); - if (output == NULL) { - GOTO (done); - } - } + mongoc_stream_t *const stream = cmd->server_stream->stream; - if (cluster->client->in_exhaust) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_IN_EXHAUST, - "A cursor derived from this client is in exhaust."); - GOTO (done); + mongoc_buffer_t buffer; + _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); + + void *decompressed_data = NULL; + size_t decompressed_data_len = 0u; + + if (!_mongoc_buffer_append_from_stream ( + &buffer, stream, sizeof (int32_t), cluster->sockettimeoutms, error)) { + RUN_CMD_ERR (MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "socket error or timeout"); + _handle_network_error (cluster, cmd->server_stream, error); + goto done; } - /* - * send and receive - */ - if (!_mongoc_stream_writev_full (stream, - cluster->iov.data, - cluster->iov.len, - cluster->sockettimeoutms, - error)) { - _handle_network_error ( - cluster, cmd->server_stream, true /* handshake complete */, error); + const int32_t message_length = _int32_from_le (buffer.data); - /* add info about the command to writev_full's error message */ - RUN_CMD_ERR_DECORATE; - GOTO (done); + if (message_length < message_header_length || + message_length > MONGOC_DEFAULT_MAX_MSG_SIZE) { + RUN_CMD_ERR (MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "invalid message length"); + _handle_network_error (cluster, cmd->server_stream, error); + goto done; } - if (reply_header_size != mongoc_stream_read (stream, - &reply_header_buf, - reply_header_size, - reply_header_size, - cluster->sockettimeoutms)) { + const size_t remaining_bytes = (size_t) message_length - sizeof (int32_t); + + if (!_mongoc_buffer_append_from_stream ( + &buffer, stream, remaining_bytes, cluster->sockettimeoutms, error)) { RUN_CMD_ERR (MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "socket error or timeout"); - - _handle_network_error ( - cluster, cmd->server_stream, true /* handshake complete */, error); - GOTO (done); + _handle_network_error (cluster, cmd->server_stream, error); + goto done; } - memcpy (&msg_len, reply_header_buf, 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - if ((msg_len < reply_header_size) || - (msg_len > MONGOC_DEFAULT_MAX_MSG_SIZE)) { - _handle_network_error ( - cluster, cmd->server_stream, true /* handshake complete */, error); - GOTO (done); + if (!mcd_rpc_message_from_data_in_place ( + rpc, buffer.data, buffer.len, NULL)) { + RUN_CMD_ERR (MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "malformed reply from server"); + goto done; } - if (!_mongoc_rpc_scatter_reply_header_only ( - &rpc, reply_header_buf, reply_header_size)) { - _handle_network_error ( - cluster, cmd->server_stream, true /* handshake complete */, error); - GOTO (done); + mcd_rpc_message_ingress (rpc); + + if (!mcd_rpc_message_decompress_if_necessary ( + rpc, &decompressed_data, &decompressed_data_len)) { + RUN_CMD_ERR (MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "could not decompress server reply"); + goto done; } - doc_len = (size_t) msg_len - reply_header_size; - - if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_COMPRESSED) { - bson_t tmp = BSON_INITIALIZER; - uint8_t *buf = NULL; - size_t len = BSON_UINT32_FROM_LE (rpc.compressed.uncompressed_size) + - sizeof (mongoc_rpc_header_t); - - reply_buf = bson_malloc0 (msg_len); - memcpy (reply_buf, reply_header_buf, reply_header_size); - - if (doc_len != mongoc_stream_read (stream, - reply_buf + reply_header_size, - doc_len, - doc_len, - cluster->sockettimeoutms)) { - RUN_CMD_ERR (MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "socket error or timeout"); - _handle_network_error ( - cluster, cmd->server_stream, true /* handshake complete */, error); - GOTO (done); - } - if (!_mongoc_rpc_scatter (&rpc, reply_buf, msg_len)) { - GOTO (done); - } - buf = bson_malloc0 (len); - if (!_mongoc_rpc_decompress (&rpc, buf, len)) { + { + bson_t body; + + if (!mcd_rpc_message_get_body (rpc, &body)) { RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Could not decompress server reply"); - bson_free (reply_buf); - bson_free (buf); - GOTO (done); + "malformed reply from server"); + goto done; } - _mongoc_rpc_swab_from_le (&rpc); + bson_copy_to (&body, reply); + bson_destroy (&body); + } - if (!_mongoc_rpc_get_first_document (&rpc, &tmp)) { - RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Corrupt compressed OP_QUERY reply from server"); - bson_free (reply_buf); - bson_free (buf); - GOTO (done); - } - bson_copy_to (&tmp, reply_ptr); - bson_free (reply_buf); - bson_free (buf); - } else if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_REPLY && - BSON_UINT32_FROM_LE (rpc.reply_header.n_returned) == 1) { - reply_buf = bson_reserve_buffer (reply_ptr, (uint32_t) doc_len); - BSON_ASSERT (reply_buf); - - if (doc_len != mongoc_stream_read (stream, - (void *) reply_buf, - doc_len, - doc_len, - cluster->sockettimeoutms)) { - RUN_CMD_ERR (MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "socket error or timeout"); - _handle_network_error ( - cluster, cmd->server_stream, true /* handshake complete */, error); - GOTO (done); - } - _mongoc_rpc_swab_from_le (&rpc); - } else { + if (!_mongoc_cmd_check_ok ( + reply, cluster->client->error_api_version, error)) { + goto done; + } + + ret = true; + +done: + bson_free (decompressed_data); + _mongoc_buffer_destroy (&buffer); + + return ret; +} + +static bool +mongoc_cluster_run_command_opquery (mongoc_cluster_t *cluster, + mongoc_cmd_t *cmd, + int32_t compressor_id, + bson_t *reply, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT_PARAM (cmd); + BSON_ASSERT_PARAM (cmd->server_stream); + BSON_ASSERT_PARAM (reply); + BSON_ASSERT_PARAM (error); + + ENTRY; + + bool ret = false; + + bson_init (reply); + error->code = 0; + + mcd_rpc_message *const rpc = mcd_rpc_message_new (); + + if (!_mongoc_cluster_run_command_opquery_send ( + cluster, cmd, compressor_id, rpc, error)) { GOTO (done); } - if (!_mongoc_cmd_check_ok ( - reply_ptr, cluster->client->error_api_version, error)) { + mcd_rpc_message_reset (rpc); + + if (!_mongoc_cluster_run_command_opquery_recv ( + cluster, cmd, rpc, reply, error)) { GOTO (done); } ret = true; done: - if (!ret && error->code == 0) { /* generic error */ RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid reply from server."); + "invalid reply from server"); } - if (reply_ptr == &reply_local) { - bson_destroy (reply_ptr); - } - bson_free (output); - bson_free (cmd_ns); + mcd_rpc_message_destroy (rpc); RETURN (ret); } -bool +static bool _in_sharded_txn (const mongoc_client_session_t *session) { return session && _mongoc_client_session_in_txn_or_ending (session) && @@ -454,6 +501,24 @@ _in_sharded_txn (const mongoc_client_session_t *session) MONGOC_TOPOLOGY_SHARDED; } +static bool +_in_sharded_or_loadbalanced_txn (const mongoc_client_session_t *session) +{ + if (!session) { + return false; + } + + if (!_mongoc_client_session_in_txn_or_ending (session)) { + return false; + } + + mongoc_topology_description_type_t type = + _mongoc_topology_get_type (session->client->topology); + + return (type == MONGOC_TOPOLOGY_SHARDED) || + (type == MONGOC_TOPOLOGY_LOAD_BALANCED); +} + static void _handle_txn_error_labels (bool cmd_ret, const bson_error_t *cmd_err, @@ -465,7 +530,7 @@ _handle_txn_error_labels (bool cmd_ret, } _mongoc_write_error_handle_labels ( - cmd_ret, cmd_err, reply, cmd->server_stream->sd->max_wire_version); + cmd_ret, cmd_err, reply, cmd->server_stream->sd); } /* @@ -493,7 +558,7 @@ mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster, bson_error_t *error) { bool retval; - uint32_t request_id = ++cluster->request_id; + const int32_t request_id = ++cluster->request_id; uint32_t server_id; mongoc_apm_callbacks_t *callbacks; mongoc_apm_command_started_t started_event; @@ -503,7 +568,6 @@ mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster, const mongoc_server_stream_t *server_stream; bson_t reply_local; bson_error_t error_local; - int32_t compressor_id; bson_iter_t iter; bson_t encrypted = BSON_INITIALIZER; bson_t decrypted = BSON_INITIALIZER; @@ -512,7 +576,6 @@ mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster, server_stream = cmd->server_stream; server_id = server_stream->sd->id; - compressor_id = mongoc_server_description_compressor_id (server_stream->sd); callbacks = &cluster->client->apm_callbacks; if (!reply) { @@ -545,20 +608,14 @@ mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster, mongoc_apm_command_started_cleanup (&started_event); } - if (mongoc_cluster_uses_server_api (cluster) || - server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) { - retval = mongoc_cluster_run_opmsg (cluster, cmd, reply, error); - } else { - retval = mongoc_cluster_run_command_opquery ( - cluster, cmd, compressor_id, reply, error); - } + retval = mongoc_cluster_run_opmsg (cluster, cmd, reply, error); if (retval && callbacks->succeeded) { bson_t fake_reply = BSON_INITIALIZER; /* * Unacknowledged writes must provide a CommandSucceededEvent with an * {ok: 1} reply. - * https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst#unacknowledged-acknowledged-writes + * https://github.com/mongodb/specifications/blob/master/source/command-logging-and-monitoring/command-logging-and-monitoring.rst#unacknowledged-acknowledged-writes */ if (!cmd->is_acknowledged) { bson_append_int32 (&fake_reply, "ok", 2, 1); @@ -616,7 +673,7 @@ mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster, _handle_txn_error_labels (retval, error, cmd, reply); - if (retval && _in_sharded_txn (cmd->session) && + if (retval && _in_sharded_or_loadbalanced_txn (cmd->session) && bson_iter_init_find (&iter, reply, "recoveryToken")) { bson_destroy (cmd->session->recovery_token); if (BSON_ITER_HOLDS_DOCUMENT (&iter)) { @@ -643,6 +700,14 @@ mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster, } +static bool +_should_use_op_msg (const mongoc_cluster_t *cluster) +{ + return mongoc_cluster_uses_server_api (cluster) || + mongoc_cluster_uses_loadbalanced (cluster); +} + + /* *-------------------------------------------------------------------------- * @@ -684,8 +749,8 @@ mongoc_cluster_run_command_private (mongoc_cluster_t *cluster, server_stream = cmd->server_stream; - if (mongoc_cluster_uses_server_api (cluster) || - server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) { + if (_should_use_op_msg (cluster) || + server_stream->sd->max_wire_version >= WIRE_VERSION_MIN) { retval = mongoc_cluster_run_opmsg (cluster, cmd, reply, error); } else { retval = @@ -766,7 +831,6 @@ _stream_run_hello (mongoc_cluster_t *cluster, const char *address, uint32_t server_id, bool negotiate_sasl_supported_mechs, - mongoc_scram_cache_t *scram_cache, mongoc_scram_t *scram, bson_t *speculative_auth_response /* OUT */, bson_error_t *error) @@ -780,7 +844,6 @@ _stream_run_hello (mongoc_cluster_t *cluster, mongoc_server_description_t *ret_handshake_sd; mongoc_server_stream_t *server_stream; bool r; - bson_iter_t iter; mongoc_ssl_opt_t *ssl_opts = NULL; mc_shared_tpld td = mc_tpld_take_ref (BSON_ASSERT_PTR_INLINE (cluster)->client->topology); @@ -798,7 +861,7 @@ _stream_run_hello (mongoc_cluster_t *cluster, #endif _mongoc_topology_scanner_add_speculative_authentication ( - &handshake_command, cluster->uri, ssl_opts, scram_cache, scram); + &handshake_command, cluster->uri, ssl_opts, scram); } if (negotiate_sasl_supported_mechs) { @@ -827,17 +890,9 @@ _stream_run_hello (mongoc_cluster_t *cluster, to either an op_msg or op_query: */ memset (&hello_cmd, 0, sizeof (hello_cmd)); - - hello_cmd.db_name = "admin"; - hello_cmd.command = &handshake_command; - hello_cmd.command_name = _mongoc_get_command_name (&handshake_command); - hello_cmd.server_stream = server_stream; - - hello_cmd.is_acknowledged = true; - /* Use OP_QUERY for the handshake, unless the user has specified an * API version; the correct hello_cmd has already been selected: */ - if (!mongoc_cluster_uses_server_api (cluster)) { + if (!_should_use_op_msg (cluster)) { /* Complete OPCODE_QUERY setup: */ hello_cmd.query_flags = MONGOC_QUERY_SECONDARY_OK; } else { @@ -845,17 +900,25 @@ _stream_run_hello (mongoc_cluster_t *cluster, bson_append_utf8 (&handshake_command, "$db", 3, "admin", 5); } + hello_cmd.db_name = "admin"; + hello_cmd.command = &handshake_command; + hello_cmd.command_name = _mongoc_get_command_name (&handshake_command); + hello_cmd.server_stream = server_stream; + hello_cmd.is_acknowledged = true; + if (!mongoc_cluster_run_command_private ( cluster, &hello_cmd, &reply, error)) { if (negotiate_sasl_supported_mechs) { - if (bson_iter_init_find (&iter, &reply, "ok") && - !bson_iter_as_bool (&iter)) { - /* hello response returned ok: 0. According to auth spec: "If the - * hello of the MongoDB Handshake fails with an error, drivers - * MUST treat this an authentication error." */ - error->domain = MONGOC_ERROR_CLIENT; - error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; - } + bsonParse (reply, + find (allOf (key ("ok"), isFalse), // + do ({ + /* hello response returned ok: 0. According to + * auth spec: "If the hello of the MongoDB + * Handshake fails with an error, drivers MUST + * treat this an authentication error." */ + error->domain = MONGOC_ERROR_CLIENT; + error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; + }))); } mongoc_server_stream_cleanup (server_stream); @@ -921,7 +984,6 @@ static mongoc_server_description_t * _cluster_run_hello (mongoc_cluster_t *cluster, mongoc_cluster_node_t *node, uint32_t server_id, - mongoc_scram_cache_t *scram_cache, mongoc_scram_t *scram /* OUT */, bson_t *speculative_auth_response /* OUT */, bson_error_t *error /* OUT */) @@ -939,7 +1001,6 @@ _cluster_run_hello (mongoc_cluster_t *cluster, node->connection_address, server_id, _mongoc_uri_requires_auth_negotiation (cluster->uri), - scram_cache, scram, speculative_auth_response, error); @@ -996,7 +1057,7 @@ _mongoc_cluster_build_basic_auth_digest (mongoc_cluster_t *cluster, * with a MongoDB server. More information on the format can be found * at the following location: * - * http://docs.mongodb.org/meta-driver/latest/legacy/ + * https://www.mongodb.com/docs/meta-driver/latest/legacy/ * implement-authentication-in-driver/ */ @@ -1352,9 +1413,17 @@ _mongoc_cluster_auth_node_x509 (mongoc_cluster_t *cluster, bool mongoc_cluster_uses_server_api (const mongoc_cluster_t *cluster) { + BSON_ASSERT_PARAM (cluster); return mongoc_client_uses_server_api (cluster->client); } +bool +mongoc_cluster_uses_loadbalanced (const mongoc_cluster_t *cluster) +{ + BSON_ASSERT_PARAM (cluster); + return mongoc_client_uses_loadbalanced (cluster->client); +} + #ifdef MONGOC_ENABLE_CRYPTO void _mongoc_cluster_init_scram (const mongoc_cluster_t *cluster, @@ -1362,11 +1431,6 @@ _mongoc_cluster_init_scram (const mongoc_cluster_t *cluster, mongoc_crypto_hash_algorithm_t algo) { _mongoc_uri_init_scram (cluster->uri, scram, algo); - - /* Apply previously cached SCRAM secrets if available */ - if (cluster->scram_cache) { - _mongoc_scram_set_cache (scram, cluster->scram_cache); - } } /* @@ -1580,8 +1644,10 @@ _mongoc_cluster_scram_handle_reply (mongoc_scram_t *scram, BSON_ASSERT (scram); - if (bson_iter_init_find (&iter, reply, "done") && - bson_iter_as_bool (&iter)) { + bool is_done = false; + bsonParse (*reply, find (key ("done"), storeBool (is_done))); + + if (is_done) { if (scram->step < 2) { /* Prior to step 2, we haven't even received server proof. */ bson_set_error (error, @@ -1726,13 +1792,6 @@ _mongoc_cluster_auth_scram_continue ( TRACE ("%s", "SCRAM: authenticated"); - /* Save cached SCRAM secrets for future use */ - if (cluster->scram_cache) { - _mongoc_scram_cache_destroy (cluster->scram_cache); - } - - cluster->scram_cache = _mongoc_scram_get_cache (scram); - return true; } @@ -2120,7 +2179,6 @@ _cluster_add_node (mongoc_cluster_t *cluster, handshake_sd = _cluster_run_hello (cluster, cluster_node, server_id, - cluster->scram_cache, &scram, &speculative_auth_response, error); @@ -2256,7 +2314,7 @@ _try_get_server_stream (mongoc_cluster_t *cluster, } } -mongoc_server_stream_t * +static mongoc_server_stream_t * _mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster, uint32_t server_id, bool reconnect_ok, @@ -2293,12 +2351,14 @@ _mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster, * into account. */ + _mongoc_bson_init_if_set (reply); + + // Add a transient transaction label if applicable. + _mongoc_add_transient_txn_error (cs, reply); + /* Update the topology */ tdmod = mc_tpld_modify_begin (topology); - /* Add a transient transaction label if applicable. */ - _mongoc_bson_init_with_transient_txn_error (cs, reply); - /* When establishing a new connection in load balanced mode, drivers MUST * NOT perform SDAM error handling for any errors that occur before the * MongoDB Handshake. */ @@ -2357,8 +2417,10 @@ mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster, bson_t *reply, bson_error_t *error) { - mongoc_server_stream_t *server_stream = NULL; - bson_error_t err_local = {0}; + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT (cs || true); + BSON_ASSERT (reply || true); + BSON_ASSERT (error || true); ENTRY; @@ -2373,12 +2435,10 @@ mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster, RETURN (NULL); } - if (!error) { - error = &err_local; - } - server_stream = _mongoc_cluster_stream_for_server ( - cluster, server_id, reconnect_ok, cs, reply, error); + mongoc_server_stream_t *const server_stream = + _mongoc_cluster_stream_for_server ( + cluster, server_id, reconnect_ok, cs, reply, error); if (_in_sharded_txn (cs)) { _mongoc_client_session_pin (cs, server_id); @@ -2725,12 +2785,6 @@ mongoc_cluster_destroy (mongoc_cluster_t *cluster) /* INOUT */ _mongoc_array_destroy (&cluster->iov); -#ifdef MONGOC_ENABLE_CRYPTO - if (cluster->scram_cache) { - _mongoc_scram_cache_destroy (cluster->scram_cache); - } -#endif - EXIT; } @@ -2740,22 +2794,29 @@ _mongoc_cluster_select_server_id (mongoc_client_session_t *cs, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_prefs, bool *must_use_primary, + const mongoc_deprioritized_servers_t *ds, bson_error_t *error) { + BSON_ASSERT (cs || true); + BSON_ASSERT_PARAM (topology); + BSON_ASSERT (read_prefs || true); + BSON_ASSERT_PARAM (must_use_primary); + BSON_ASSERT (error || true); + uint32_t server_id; if (_in_sharded_txn (cs)) { server_id = cs->server_id; if (!server_id) { server_id = mongoc_topology_select_server_id ( - topology, optype, read_prefs, must_use_primary, error); + topology, optype, read_prefs, must_use_primary, ds, error); if (server_id) { _mongoc_client_session_pin (cs, server_id); } } } else { server_id = mongoc_topology_select_server_id ( - topology, optype, read_prefs, must_use_primary, error); + topology, optype, read_prefs, must_use_primary, ds, error); /* Transactions Spec: Additionally, any non-transaction operation using a * pinned ClientSession MUST unpin the session and the operation MUST * perform normal server selection. */ @@ -2790,9 +2851,17 @@ _mongoc_cluster_stream_for_optype (mongoc_cluster_t *cluster, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_prefs, mongoc_client_session_t *cs, + bool is_retryable, + const mongoc_deprioritized_servers_t *ds, bson_t *reply, bson_error_t *error) { + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT (read_prefs || true); + BSON_ASSERT (cs || true); + BSON_ASSERT (reply || true); + BSON_ASSERT (error || true); + mongoc_server_stream_t *server_stream; uint32_t server_id; mongoc_topology_t *topology = cluster->client->topology; @@ -2803,66 +2872,162 @@ _mongoc_cluster_stream_for_optype (mongoc_cluster_t *cluster, BSON_ASSERT (cluster); server_id = _mongoc_cluster_select_server_id ( - cs, topology, optype, read_prefs, &must_use_primary, error); + cs, topology, optype, read_prefs, &must_use_primary, ds, error); if (!server_id) { - _mongoc_bson_init_with_transient_txn_error (cs, reply); + if (reply) { + bson_init (reply); + _mongoc_add_transient_txn_error (cs, reply); + } RETURN (NULL); } if (!mongoc_cluster_check_interval (cluster, server_id)) { /* Server Selection Spec: try once more */ server_id = _mongoc_cluster_select_server_id ( - cs, topology, optype, read_prefs, &must_use_primary, error); + cs, topology, optype, read_prefs, &must_use_primary, ds, error); if (!server_id) { - _mongoc_bson_init_with_transient_txn_error (cs, reply); + if (reply) { + bson_init (reply); + _mongoc_add_transient_txn_error (cs, reply); + } RETURN (NULL); } } - /* connect or reconnect to server if necessary */ - server_stream = _mongoc_cluster_stream_for_server ( - cluster, server_id, true /* reconnect_ok */, cs, reply, error); + bson_t first_reply; + bson_error_t first_error = {0}; + + server_stream = _mongoc_cluster_stream_for_server (cluster, + server_id, + true /* reconnect_ok */, + cs, + &first_reply, + &first_error); + if (server_stream) { server_stream->must_use_primary = must_use_primary; + RETURN (server_stream); } - RETURN (server_stream); + // Important: authentication errors are also considered retryable even if + // they not considered a network error. + const bool retryable_error = _mongoc_error_is_network (&first_error) || + _mongoc_error_is_auth (&first_error); + + if (is_retryable && retryable_error) { + bson_t retry_reply; + bson_error_t retry_error = {0}; + + server_stream = + _mongoc_cluster_stream_for_server (cluster, + server_id, + true /* reconnect_ok */, + cs, + &retry_reply, + &retry_error); + + if (server_stream) { + server_stream->must_use_primary = must_use_primary; + server_stream->retry_attempted = true; + bson_destroy (&first_reply); + RETURN (server_stream); + } + + if (optype != MONGOC_SS_READ) { + // Retryable Writes Spec: When the driver encounters a network error + // establishing an initial connection to a server, it MUST add a + // RetryableWriteError label to that error if the MongoClient + // performing the operation has the retryWrites configuration option + // set to true. + _mongoc_write_error_append_retryable_label (&first_reply); + } + + bson_destroy (&retry_reply); + } + + // Retryable Writes Spec: If the driver cannot select a server for the retry + // attempt [...], retrying is not possible and drivers MUST raise the + // original retryable error. + { + if (reply) { + bson_copy_to (&first_reply, reply); + } + + bson_destroy (&first_reply); + + if (error) { + *error = first_error; + } + } + + RETURN (NULL); } mongoc_server_stream_t * mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster, const mongoc_read_prefs_t *read_prefs, mongoc_client_session_t *cs, + const mongoc_deprioritized_servers_t *ds, bson_t *reply, - bool has_write_stage, bson_error_t *error) { - const mongoc_read_prefs_t *prefs_override = read_prefs; - - if (_mongoc_client_session_in_txn (cs)) { - prefs_override = cs->txn.opts.read_prefs; - } - - return _mongoc_cluster_stream_for_optype ( - cluster, - /* Narrow down the optype if this is an aggregate op with a write stage */ - has_write_stage ? MONGOC_SS_AGGREGATE_WITH_WRITE : MONGOC_SS_READ, - prefs_override, - cs, - reply, - error); + const mongoc_read_prefs_t *const prefs_override = + _mongoc_client_session_in_txn (cs) ? cs->txn.opts.read_prefs : read_prefs; + + // Retryable Reads Spec: This boolean option determines whether retryable + // behavior will be applied to all read operations executed within the + // MongoClient. + const bool is_retryable = mongoc_uri_get_option_as_bool ( + cluster->uri, MONGOC_URI_RETRYREADS, MONGOC_DEFAULT_RETRYREADS); + + return _mongoc_cluster_stream_for_optype (cluster, + MONGOC_SS_READ, + prefs_override, + cs, + is_retryable, + ds, + reply, + error); } mongoc_server_stream_t * mongoc_cluster_stream_for_writes (mongoc_cluster_t *cluster, mongoc_client_session_t *cs, + const mongoc_deprioritized_servers_t *ds, bson_t *reply, bson_error_t *error) { + const bool is_retryable = mongoc_uri_get_option_as_bool ( + cluster->uri, MONGOC_URI_RETRYWRITES, MONGOC_DEFAULT_RETRYWRITES); + return _mongoc_cluster_stream_for_optype ( - cluster, MONGOC_SS_WRITE, NULL, cs, reply, error); + cluster, MONGOC_SS_WRITE, NULL, cs, is_retryable, ds, reply, error); +} + +mongoc_server_stream_t * +mongoc_cluster_stream_for_aggr_with_write ( + mongoc_cluster_t *cluster, + const mongoc_read_prefs_t *read_prefs, + mongoc_client_session_t *cs, + bson_t *reply, + bson_error_t *error) +{ + const mongoc_read_prefs_t *const prefs_override = + _mongoc_client_session_in_txn (cs) ? cs->txn.opts.read_prefs : read_prefs; + + const bool is_retryable = mongoc_uri_get_option_as_bool ( + cluster->uri, MONGOC_URI_RETRYWRITES, MONGOC_DEFAULT_RETRYWRITES); + + return _mongoc_cluster_stream_for_optype (cluster, + MONGOC_SS_AGGREGATE_WITH_WRITE, + prefs_override, + cs, + is_retryable, + NULL, + reply, + error); } static bool @@ -3112,85 +3277,73 @@ mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id) } -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_legacy_rpc_sendv_to_server -- - * - * Sends the given RPCs to the given server. Used for OP_QUERY cursors, - * OP_KILLCURSORS, and legacy writes with OP_INSERT, OP_UPDATE, and - * OP_DELETE. This function is *not* in the OP_QUERY command path. - * - * Returns: - * True if successful. - * - * Side effects: - * @rpc may be mutated and should be considered invalid after calling - * this method. - * - * @error may be set. - * - *-------------------------------------------------------------------------- - */ - bool mongoc_cluster_legacy_rpc_sendv_to_server ( mongoc_cluster_t *cluster, - mongoc_rpc_t *rpc, + mcd_rpc_message *rpc, mongoc_server_stream_t *server_stream, bson_error_t *error) { - uint32_t server_id; - int32_t max_msg_size; - bool ret = false; - int32_t compressor_id = 0; - char *output = NULL; + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (server_stream); + BSON_ASSERT_PARAM (error); ENTRY; - BSON_ASSERT (cluster); - BSON_ASSERT (rpc); - BSON_ASSERT (server_stream); + bool ret = false; - server_id = server_stream->sd->id; + void *compressed_data = NULL; + size_t compressed_data_len = 0u; + mongoc_iovec_t *iovecs = NULL; + size_t num_iovecs = 0u; if (cluster->client->in_exhaust) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_IN_EXHAUST, - "A cursor derived from this client is in exhaust."); + "a cursor derived from this client is in exhaust"); GOTO (done); } - _mongoc_array_clear (&cluster->iov); - compressor_id = mongoc_server_description_compressor_id (server_stream->sd); - - _mongoc_rpc_gather (rpc, &cluster->iov); - _mongoc_rpc_swab_to_le (rpc); + const int32_t compressor_id = + mongoc_server_description_compressor_id (server_stream->sd); - if (compressor_id != -1) { - output = _mongoc_rpc_compress (cluster, compressor_id, rpc, error); - if (output == NULL) { - GOTO (done); - } + if (compressor_id != -1 && + !mcd_rpc_message_compress ( + rpc, + compressor_id, + _compression_level_from_uri (compressor_id, cluster->uri), + &compressed_data, + &compressed_data_len, + error)) { + GOTO (done); } - max_msg_size = mongoc_server_stream_max_msg_size (server_stream); + const uint32_t server_id = server_stream->sd->id; + const int32_t max_msg_size = + mongoc_server_stream_max_msg_size (server_stream); + + const int32_t message_length = mcd_rpc_header_get_message_length (rpc); - if (BSON_UINT32_FROM_LE (rpc->header.msg_len) > max_msg_size) { + if (message_length > max_msg_size) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_TOO_BIG, - "Attempted to send an RPC larger than the " - "max allowed message size. Was %u, allowed %u.", - BSON_UINT32_FROM_LE (rpc->header.msg_len), + "attempted to send an RPC message with length %" PRId32 + " which exceeds the maximum allowed length %" PRId32, + message_length, max_msg_size); GOTO (done); } + iovecs = mcd_rpc_message_to_iovecs (rpc, &num_iovecs); + BSON_ASSERT (iovecs); + + mcd_rpc_message_egress (rpc); if (!_mongoc_stream_writev_full (server_stream->stream, - cluster->iov.data, - cluster->iov.len, + iovecs, + num_iovecs, cluster->sockettimeoutms, error)) { GOTO (done); @@ -3201,151 +3354,121 @@ mongoc_cluster_legacy_rpc_sendv_to_server ( ret = true; done: - - if (compressor_id) { - bson_free (output); - } + bson_free (iovecs); + bson_free (compressed_data); RETURN (ret); } -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_try_recv -- - * - * Tries to receive the next event from the MongoDB server. - * The contents are loaded into @buffer and then - * scattered into the @rpc structure. @rpc is valid as long as - * @buffer contains the contents read into it. - * - * Callers that can optimize a reuse of @buffer should do so. It - * can save many memory allocations. - * - * Returns: - * True if successful. - * - * Side effects: - * @rpc is set on success, @error on failure. - * @buffer will be filled with the input data. - * - *-------------------------------------------------------------------------- - */ - bool mongoc_cluster_try_recv (mongoc_cluster_t *cluster, - mongoc_rpc_t *rpc, + mcd_rpc_message *rpc, mongoc_buffer_t *buffer, mongoc_server_stream_t *server_stream, bson_error_t *error) { - bson_error_t err_local; - int32_t msg_len; - int32_t max_msg_size; - off_t pos; + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (server_stream); + BSON_ASSERT_PARAM (error); ENTRY; - BSON_ASSERT (cluster); - BSON_ASSERT (rpc); - BSON_ASSERT (buffer); - BSON_ASSERT (server_stream); - + bool ret = false; TRACE ("Waiting for reply from server_id \"%u\"", server_stream->sd->id); - if (!error) { - error = &err_local; - } + const size_t offset = buffer->len; - /* - * Buffer the message length to determine how much more to read. - */ - pos = buffer->len; - if (!_mongoc_buffer_append_from_stream ( - buffer, server_stream->stream, 4, cluster->sockettimeoutms, error)) { + if (!_mongoc_buffer_append_from_stream (buffer, + server_stream->stream, + sizeof (int32_t), + cluster->sockettimeoutms, + error)) { MONGOC_DEBUG ( - "Could not read 4 bytes, stream probably closed or timed out"); + "could not read message length, stream probably closed or timed out"); mongoc_counter_protocol_ingress_error_inc (); - _handle_network_error ( - cluster, server_stream, true /* handshake complete */, error); - RETURN (false); + _handle_network_error (cluster, server_stream, error); + GOTO (done); } - /* - * Read the msg length from the buffer. - */ - memcpy (&msg_len, &buffer->data[pos], 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - max_msg_size = mongoc_server_stream_max_msg_size (server_stream); - if ((msg_len < 16) || (msg_len > max_msg_size)) { + const int32_t message_length = _int32_from_le (buffer->data + offset); + + const int32_t max_msg_size = + mongoc_server_stream_max_msg_size (server_stream); + + if (message_length < message_header_length || + message_length > max_msg_size) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Corrupt or malicious reply received."); - _handle_network_error ( - cluster, server_stream, true /* handshake complete */, error); + "message length %" PRId32 + " is not within valid range of %" PRId32 "-%" PRId32 + " bytes", + message_header_length, + message_length, + server_stream->sd->max_msg_size); + _handle_network_error (cluster, server_stream, error); mongoc_counter_protocol_ingress_error_inc (); - RETURN (false); + GOTO (done); } - /* - * Read the rest of the message from the stream. - */ + const size_t remaining_bytes = (size_t) message_length - sizeof (int32_t); + if (!_mongoc_buffer_append_from_stream (buffer, server_stream->stream, - msg_len - 4, + remaining_bytes, cluster->sockettimeoutms, error)) { - _handle_network_error ( - cluster, server_stream, true /* handshake complete */, error); + _handle_network_error (cluster, server_stream, error); mongoc_counter_protocol_ingress_error_inc (); - RETURN (false); + GOTO (done); } - /* - * Scatter the buffer into the rpc structure. - */ - if (!_mongoc_rpc_scatter (rpc, &buffer->data[pos], msg_len)) { + if (!mcd_rpc_message_from_data_in_place ( + rpc, buffer->data + offset, (size_t) message_length, NULL)) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Failed to decode reply from server."); - _handle_network_error ( - cluster, server_stream, true /* handshake complete */, error); + "failed to decode reply from server"); + _handle_network_error (cluster, server_stream, error); mongoc_counter_protocol_ingress_error_inc (); - RETURN (false); + GOTO (done); } - if (BSON_UINT32_FROM_LE (rpc->header.opcode) == MONGOC_OPCODE_COMPRESSED) { - uint8_t *buf = NULL; - size_t len = BSON_UINT32_FROM_LE (rpc->compressed.uncompressed_size) + - sizeof (mongoc_rpc_header_t); + mcd_rpc_message_ingress (rpc); - buf = bson_malloc0 (len); - if (!_mongoc_rpc_decompress (rpc, buf, len)) { - bson_free (buf); - bson_set_error (error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Could not decompress server reply"); - RETURN (false); - } + void *decompressed_data = NULL; + size_t decompressed_data_len = 0u; + + if (!mcd_rpc_message_decompress_if_necessary ( + rpc, &decompressed_data, &decompressed_data_len)) { + bson_set_error (error, + MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "could not decompress server reply"); + GOTO (done); + } + if (decompressed_data) { _mongoc_buffer_destroy (buffer); - _mongoc_buffer_init (buffer, buf, len, NULL, NULL); + _mongoc_buffer_init ( + buffer, decompressed_data, decompressed_data_len, NULL, NULL); } - _mongoc_rpc_swab_from_le (rpc); - RETURN (true); + ret = true; + +done: + + return ret; } static void network_error_reply (bson_t *reply, mongoc_cmd_t *cmd) { - bson_t labels; + bson_array_builder_t *labels; if (reply) { bson_init (reply); @@ -3374,219 +3497,510 @@ network_error_reply (bson_t *reply, mongoc_cmd_t *cmd) return; } - BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels); - BSON_APPEND_UTF8 (&labels, "0", TRANSIENT_TXN_ERR); - bson_append_array_end (reply, &labels); + BSON_APPEND_ARRAY_BUILDER_BEGIN (reply, "errorLabels", &labels); + bson_array_builder_append_utf8 (labels, TRANSIENT_TXN_ERR, -1); + bson_append_array_builder_end (reply, labels); } } } +static bool +_mongoc_cluster_run_opmsg_send (mongoc_cluster_t *cluster, + mongoc_cmd_t *cmd, + mcd_rpc_message *rpc, + bson_t *reply, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT_PARAM (cmd); + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (reply); + BSON_ASSERT_PARAM (error); + + mongoc_server_stream_t *const server_stream = cmd->server_stream; + + const uint32_t flags = + (cmd->is_acknowledged ? MONGOC_OP_MSG_FLAG_NONE + : MONGOC_OP_MSG_FLAG_MORE_TO_COME) | + (cmd->op_msg_is_exhaust ? MONGOC_OP_MSG_FLAG_EXHAUST_ALLOWED + : MONGOC_OP_MSG_FLAG_NONE); + + { + int32_t message_length = 0; + + message_length += mcd_rpc_header_set_message_length (rpc, 0); + message_length += + mcd_rpc_header_set_request_id (rpc, ++cluster->request_id); + message_length += mcd_rpc_header_set_response_to (rpc, 0); + message_length += mcd_rpc_header_set_op_code (rpc, MONGOC_OP_CODE_MSG); + + mcd_rpc_op_msg_set_sections_count (rpc, cmd->payload ? 2u : 1u); + + message_length += mcd_rpc_op_msg_set_flag_bits (rpc, flags); + message_length += mcd_rpc_op_msg_section_set_kind (rpc, 0u, 0); + message_length += mcd_rpc_op_msg_section_set_body ( + rpc, 0u, bson_get_data (cmd->command)); + + if (cmd->payload) { + BSON_ASSERT (bson_in_range_signed (size_t, cmd->payload_size)); + + const size_t section_length = sizeof (int32_t) + + strlen (cmd->payload_identifier) + 1u + + (size_t) cmd->payload_size; + BSON_ASSERT (bson_in_range_unsigned (int32_t, section_length)); + + message_length += mcd_rpc_op_msg_section_set_kind (rpc, 1u, 1); + message_length += mcd_rpc_op_msg_section_set_length ( + rpc, 1u, (int32_t) section_length); + message_length += mcd_rpc_op_msg_section_set_identifier ( + rpc, 1u, cmd->payload_identifier); + message_length += mcd_rpc_op_msg_section_set_document_sequence ( + rpc, 1u, cmd->payload, (size_t) cmd->payload_size); + } + + mcd_rpc_message_set_length (rpc, message_length); + } + + void *compressed_data = NULL; + size_t compressed_data_len = 0u; + + if (mongoc_cmd_is_compressible (cmd)) { + const int32_t compressor_id = + mongoc_server_description_compressor_id (server_stream->sd); + + TRACE ( + "Function '%s' is compressible: %d", cmd->command_name, compressor_id); + + if (compressor_id != -1 && + !mcd_rpc_message_compress ( + rpc, + compressor_id, + _compression_level_from_uri (compressor_id, cluster->uri), + &compressed_data, + &compressed_data_len, + error)) { + RUN_CMD_ERR_DECORATE; + _handle_network_error (cluster, server_stream, error); + server_stream->stream = NULL; + network_error_reply (reply, cmd); + return false; + } + } + + size_t num_iovecs = 0u; + mongoc_iovec_t *const iovecs = mcd_rpc_message_to_iovecs (rpc, &num_iovecs); + BSON_ASSERT (iovecs); + + mcd_rpc_message_egress (rpc); + const bool res = _mongoc_stream_writev_full (server_stream->stream, + iovecs, + num_iovecs, + cluster->sockettimeoutms, + error); + + if (!res) { + RUN_CMD_ERR_DECORATE; + _handle_network_error (cluster, server_stream, error); + server_stream->stream = NULL; + network_error_reply (reply, cmd); + } + + bson_free (iovecs); + bson_free (compressed_data); + + return res; +} + +static bool +_mongoc_cluster_run_opmsg_recv (mongoc_cluster_t *cluster, + mongoc_cmd_t *cmd, + mcd_rpc_message *rpc, + bson_t *reply, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT_PARAM (cmd); + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (reply); + BSON_ASSERT_PARAM (error); + + bool ret = false; + + mongoc_server_stream_t *const server_stream = cmd->server_stream; + + mongoc_buffer_t buffer; + _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); + + if (!_mongoc_buffer_append_from_stream (&buffer, + server_stream->stream, + sizeof (int32_t), + cluster->sockettimeoutms, + error)) { + MONGOC_DEBUG ( + "could not read message length, stream probably closed or timed out"); + RUN_CMD_ERR_DECORATE; + _handle_network_error (cluster, server_stream, error); + server_stream->stream = NULL; + network_error_reply (reply, cmd); + goto done; + } + + const int32_t message_length = _int32_from_le (buffer.data); + + if (message_length < message_header_length || + message_length > server_stream->sd->max_msg_size) { + RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "message length %" PRId32 + " is not within valid range of %" PRId32 "-%" PRId32 + " bytes", + message_header_length, + message_length, + server_stream->sd->max_msg_size); + _handle_network_error (cluster, server_stream, error); + server_stream->stream = NULL; + network_error_reply (reply, cmd); + goto done; + } + + const size_t remaining_bytes = (size_t) message_length - sizeof (int32_t); + + if (!_mongoc_buffer_append_from_stream (&buffer, + server_stream->stream, + remaining_bytes, + cluster->sockettimeoutms, + error)) { + RUN_CMD_ERR_DECORATE; + _handle_network_error (cluster, server_stream, error); + server_stream->stream = NULL; + network_error_reply (reply, cmd); + goto done; + } + + if (!mcd_rpc_message_from_data_in_place ( + rpc, buffer.data, buffer.len, NULL)) { + RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "malformed server message"); + _handle_network_error (cluster, server_stream, error); + server_stream->stream = NULL; + network_error_reply (reply, cmd); + goto done; + } + mcd_rpc_message_ingress (rpc); + + void *decompressed_data = NULL; + size_t decompressed_data_len = 0u; + + if (!mcd_rpc_message_decompress_if_necessary ( + rpc, &decompressed_data, &decompressed_data_len)) { + bson_set_error (error, + MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "could not decompress message from server"); + _handle_network_error (cluster, server_stream, error); + server_stream->stream = NULL; + network_error_reply (reply, cmd); + GOTO (done); + } + + if (decompressed_data) { + _mongoc_buffer_destroy (&buffer); + _mongoc_buffer_init ( + &buffer, decompressed_data, decompressed_data_len, NULL, NULL); + } + + bson_t body; + + uint32_t op_msg_flags = mcd_rpc_op_msg_get_flag_bits (rpc); + cluster->client->in_exhaust = op_msg_flags & MONGOC_OP_MSG_FLAG_MORE_TO_COME; + + if (!mcd_rpc_message_get_body (rpc, &body)) { + RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "malformed message from server"); + _handle_network_error (cluster, server_stream, error); + server_stream->stream = NULL; + network_error_reply (reply, cmd); + goto done; + } + + _mongoc_topology_update_cluster_time (cluster->client->topology, &body); + + ret = + _mongoc_cmd_check_ok (&body, cluster->client->error_api_version, error); + + if (cmd->session) { + _mongoc_client_session_handle_reply ( + cmd->session, cmd->is_acknowledged, cmd->command_name, &body); + } + + bson_copy_to (&body, reply); + bson_destroy (&body); + +done: + _mongoc_buffer_destroy (&buffer); + + return ret; +} + static bool mongoc_cluster_run_opmsg (mongoc_cluster_t *cluster, mongoc_cmd_t *cmd, bson_t *reply, bson_error_t *error) { - mongoc_rpc_section_t section[2]; - mongoc_buffer_t buffer; - bson_t reply_local; /* only statically initialized */ - char *output = NULL; - mongoc_rpc_t rpc; - int32_t msg_len; - bool ok; - mongoc_server_stream_t *server_stream; + BSON_ASSERT_PARAM (cluster); + BSON_ASSERT_PARAM (cmd); + BSON_ASSERT_PARAM (reply); + BSON_ASSERT_PARAM (error); - server_stream = cmd->server_stream; if (!cmd->command_name) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, - "Empty command document"); - _mongoc_bson_init_if_set (reply); + "empty command document"); + bson_init (reply); return false; } - if (cluster->client->in_exhaust) { + + if (!cmd->op_msg_is_exhaust && cluster->client->in_exhaust) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_IN_EXHAUST, - "A cursor derived from this client is in exhaust."); - _mongoc_bson_init_if_set (reply); + "another cursor derived from this client is in exhaust"); + bson_init (reply); return false; } - _mongoc_array_clear (&cluster->iov); - _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); + bool ret = false; - rpc.header.msg_len = 0; - rpc.header.request_id = ++cluster->request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_MSG; + mcd_rpc_message *const rpc = mcd_rpc_message_new (); - if (cmd->is_acknowledged) { - rpc.msg.flags = 0; - } else { - rpc.msg.flags = MONGOC_MSG_MORE_TO_COME; + if (!cluster->client->in_exhaust && + !_mongoc_cluster_run_opmsg_send (cluster, cmd, rpc, reply, error)) { + goto done; } - rpc.msg.n_sections = 1; + if (!cmd->is_acknowledged) { + // Nothing more to do. + bson_init (reply); + ret = true; + goto done; + } - section[0].payload_type = 0; - section[0].payload.bson_document = bson_get_data (cmd->command); - rpc.msg.sections[0] = section[0]; + mcd_rpc_message_reset (rpc); - if (cmd->payload) { - section[1].payload_type = 1; - section[1].payload.sequence.size = cmd->payload_size + - strlen (cmd->payload_identifier) + 1 + - sizeof (int32_t); - section[1].payload.sequence.identifier = cmd->payload_identifier; - section[1].payload.sequence.bson_documents = cmd->payload; - rpc.msg.sections[1] = section[1]; - rpc.msg.n_sections++; + if (!_mongoc_cluster_run_opmsg_recv (cluster, cmd, rpc, reply, error)) { + goto done; } - _mongoc_rpc_gather (&rpc, &cluster->iov); - _mongoc_rpc_swab_to_le (&rpc); + ret = true; - if (mongoc_cmd_is_compressible (cmd)) { - int32_t compressor_id = - mongoc_server_description_compressor_id (server_stream->sd); +done: + mcd_rpc_message_destroy (rpc); - TRACE ( - "Function '%s' is compressible: %d", cmd->command_name, compressor_id); - if (compressor_id != -1) { - output = _mongoc_rpc_compress (cluster, compressor_id, &rpc, error); - if (output == NULL) { - _mongoc_bson_init_if_set (reply); - _mongoc_buffer_destroy (&buffer); - return false; - } - } + return ret; +} + + +bool +mcd_rpc_message_compress (mcd_rpc_message *rpc, + int32_t compressor_id, + int32_t compression_level, + void **data, + size_t *data_len, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (data); + BSON_ASSERT_PARAM (data_len); + + bool ret = false; + + char *uncompressed_message = NULL; + char *compressed_message = NULL; + mongoc_iovec_t *iovecs = NULL; + + const int32_t original_message_length = + mcd_rpc_header_get_message_length (rpc); + + // msgHeader consists of four int32 fields. + const int32_t message_header_length = 4u * sizeof (int32_t); + + // compressedMessage does not include msgHeader fields. + BSON_ASSERT (original_message_length >= message_header_length); + const size_t uncompressed_size = + (size_t) (original_message_length - message_header_length); + BSON_ASSERT (bson_in_range_unsigned (int32_t, uncompressed_size)); + + const size_t estimated_compressed_size = + mongoc_compressor_max_compressed_length (compressor_id, + uncompressed_size); + + if (estimated_compressed_size == 0u) { + bson_set_error (error, + MONGOC_ERROR_COMMAND, + MONGOC_ERROR_COMMAND_INVALID_ARG, + "Could not determine compression bounds for %s", + mongoc_compressor_id_to_name (compressor_id)); + goto fail; } - ok = _mongoc_stream_writev_full (server_stream->stream, - (mongoc_iovec_t *) cluster->iov.data, - cluster->iov.len, - cluster->sockettimeoutms, - error); - if (!ok) { - /* add info about the command to writev_full's error message */ - RUN_CMD_ERR_DECORATE; - _handle_network_error ( - cluster, server_stream, true /* handshake complete */, error); - server_stream->stream = NULL; - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; + + // Store values before they are converted to little endian. + const int32_t request_id = mcd_rpc_header_get_request_id (rpc); + const int32_t response_to = mcd_rpc_header_get_response_to (rpc); + const int32_t op_code = mcd_rpc_header_get_op_code (rpc); + + size_t num_iovecs; + iovecs = mcd_rpc_message_to_iovecs (rpc, &num_iovecs); + BSON_ASSERT (iovecs); + + uncompressed_message = bson_malloc (uncompressed_size); + BSON_ASSERT ( + _mongoc_cluster_buffer_iovec ( + iovecs, num_iovecs, message_header_length, uncompressed_message) == + uncompressed_size); + + compressed_message = bson_malloc (estimated_compressed_size); + + // This value may be passed as an argument to an in-out parameter depending + // on the compressor, not just an out-parameter. + size_t compressed_size = estimated_compressed_size; + + if (!mongoc_compress (compressor_id, + compression_level, + uncompressed_message, + uncompressed_size, + compressed_message, + &compressed_size)) { + MONGOC_WARNING ("Could not compress data with %s", + mongoc_compressor_id_to_name (compressor_id)); + goto fail; } - /* If acknowledged, wait for a server response. Otherwise, exit early */ - if (cmd->is_acknowledged) { - ok = _mongoc_buffer_append_from_stream ( - &buffer, server_stream->stream, 4, cluster->sockettimeoutms, error); - if (!ok) { - RUN_CMD_ERR_DECORATE; - _handle_network_error ( - cluster, server_stream, true /* handshake complete */, error); - server_stream->stream = NULL; - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } + mcd_rpc_message_reset (rpc); - BSON_ASSERT (buffer.len == 4); - memcpy (&msg_len, buffer.data, 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - if ((msg_len < 16) || (msg_len > server_stream->sd->max_msg_size)) { - RUN_CMD_ERR ( - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Message size %d is not within expected range 16-%d bytes", - msg_len, - server_stream->sd->max_msg_size); - _handle_network_error ( - cluster, server_stream, true /* handshake complete */, error); - server_stream->stream = NULL; - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } + { + int32_t message_len = 0; - ok = _mongoc_buffer_append_from_stream (&buffer, - server_stream->stream, - (size_t) msg_len - 4, - cluster->sockettimeoutms, - error); - if (!ok) { - RUN_CMD_ERR_DECORATE; - _handle_network_error ( - cluster, server_stream, true /* handshake complete */, error); - server_stream->stream = NULL; - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } + message_len += mcd_rpc_header_set_message_length (rpc, 0); + message_len += mcd_rpc_header_set_request_id (rpc, request_id); + message_len += mcd_rpc_header_set_response_to (rpc, response_to); + message_len += + mcd_rpc_header_set_op_code (rpc, MONGOC_OP_CODE_COMPRESSED); + message_len += mcd_rpc_op_compressed_set_original_opcode (rpc, op_code); + message_len += mcd_rpc_op_compressed_set_uncompressed_size ( + rpc, (int32_t) uncompressed_size); + message_len += + mcd_rpc_op_compressed_set_compressor_id (rpc, (uint8_t) compressor_id); + message_len += mcd_rpc_op_compressed_set_compressed_message ( + rpc, compressed_message, compressed_size); - ok = _mongoc_rpc_scatter (&rpc, buffer.data, buffer.len); - if (!ok) { - RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Malformed message from server"); - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } - if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_COMPRESSED) { - size_t len = BSON_UINT32_FROM_LE (rpc.compressed.uncompressed_size) + - sizeof (mongoc_rpc_header_t); - - output = bson_realloc (output, len); - if (!_mongoc_rpc_decompress (&rpc, (uint8_t *) output, len)) { - RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Could not decompress message from server"); - _handle_network_error ( - cluster, server_stream, true /* handshake complete */, error); - server_stream->stream = NULL; - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } - } - _mongoc_rpc_swab_from_le (&rpc); - - memcpy (&msg_len, rpc.msg.sections[0].payload.bson_document, 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - bson_init_static ( - &reply_local, rpc.msg.sections[0].payload.bson_document, msg_len); - - _mongoc_topology_update_cluster_time (cluster->client->topology, - &reply_local); - ok = _mongoc_cmd_check_ok ( - &reply_local, cluster->client->error_api_version, error); - - if (cmd->session) { - _mongoc_client_session_handle_reply (cmd->session, - cmd->is_acknowledged, - cmd->command_name, - &reply_local); - } + mcd_rpc_message_set_length (rpc, message_len); + } - if (reply) { - bson_copy_to (&reply_local, reply); - } - } else { - _mongoc_bson_init_if_set (reply); + *data = compressed_message; + *data_len = compressed_size; + compressed_message = NULL; + + ret = true; + +fail: + bson_free (compressed_message); + bson_free (uncompressed_message); + bson_free (iovecs); + + return ret; +} + +bool +mcd_rpc_message_decompress (mcd_rpc_message *rpc, void **data, size_t *data_len) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (data); + BSON_ASSERT_PARAM (data_len); + + BSON_ASSERT (mcd_rpc_header_get_op_code (rpc) == MONGOC_OP_CODE_COMPRESSED); + + // msgHeader consists of four int32 fields. + const size_t message_header_length = 4u * sizeof (int32_t); + + const size_t uncompressed_size = + (size_t) mcd_rpc_op_compressed_get_uncompressed_size (rpc); + + // uncompressedSize does not include msgHeader fields. + const size_t original_message_length = + message_header_length + uncompressed_size; + uint8_t *const ptr = bson_malloc (original_message_length); + + const int32_t message_length = original_message_length; + const int32_t request_id = mcd_rpc_header_get_request_id (rpc); + const int32_t response_to = mcd_rpc_header_get_response_to (rpc); + const int32_t op_code = mcd_rpc_op_compressed_get_original_opcode (rpc); + + // Populate the msgHeader fields. + { + uint32_t storage; + + memcpy (&storage, &message_length, sizeof (storage)); + storage = BSON_UINT32_TO_LE (storage); + memcpy (ptr + 0, &storage, sizeof (storage)); + + memcpy (&storage, &request_id, sizeof (storage)); + storage = BSON_UINT32_TO_LE (storage); + memcpy (ptr + 4, &storage, sizeof (storage)); + + memcpy (&storage, &response_to, sizeof (storage)); + storage = BSON_UINT32_TO_LE (storage); + memcpy (ptr + 8, &storage, sizeof (storage)); + + memcpy (&storage, &op_code, sizeof (storage)); + storage = BSON_UINT32_TO_LE (storage); + memcpy (ptr + 12, &storage, sizeof (storage)); } - _mongoc_buffer_destroy (&buffer); - bson_free (output); + // This value may be passed as an argument to an in-out parameter depending + // on the compressor, not just an out-parameter. + size_t actual_uncompressed_size = uncompressed_size; + + // Populate the rest of the uncompressed message. + if (!mongoc_uncompress ( + mcd_rpc_op_compressed_get_compressor_id (rpc), + mcd_rpc_op_compressed_get_compressed_message (rpc), + mcd_rpc_op_compressed_get_compressed_message_length (rpc), + ptr + message_header_length, + &actual_uncompressed_size)) { + bson_free (ptr); + return false; + } + + BSON_ASSERT (uncompressed_size == actual_uncompressed_size); + + *data_len = original_message_length; + *data = ptr; // Ownership transfer. + + mcd_rpc_message_reset (rpc); + + return mcd_rpc_message_from_data_in_place (rpc, *data, *data_len, NULL); +} + +bool +mcd_rpc_message_decompress_if_necessary (mcd_rpc_message *rpc, + void **data, + size_t *data_len) +{ + BSON_ASSERT_PARAM (rpc); + BSON_ASSERT_PARAM (data); + BSON_ASSERT_PARAM (data_len); + + if (mcd_rpc_header_get_op_code (rpc) != MONGOC_OP_CODE_COMPRESSED) { + // Nothing to do. + *data = NULL; + *data_len = 0u; + return true; + } - return ok; + return mcd_rpc_message_decompress (rpc, data, data_len); } diff --git a/src/mongoc/mongoc-cmd-private.h b/src/mongoc/mongoc-cmd-private.h index f64f91c1..602528f5 100644 --- a/src/mongoc/mongoc-cmd-private.h +++ b/src/mongoc/mongoc-cmd-private.h @@ -21,7 +21,7 @@ * Internal struct to represent a command we will send to the server - command * parameters are collected in a mongoc_cmd_parts_t until we know the server's * wire version and whether it is mongos, then we collect the parts into a - * mongoc_cmd_t, and gather that into a mongoc_rpc_t. + * mongoc_cmd_t, and gather that into an RPC message. */ #ifndef MONGOC_CMD_PRIVATE_H @@ -65,6 +65,7 @@ typedef struct _mongoc_cmd_t { mongoc_server_api_t *api; bool is_acknowledged; bool is_txn_finish; + bool op_msg_is_exhaust; } mongoc_cmd_t; @@ -107,25 +108,21 @@ mongoc_cmd_parts_set_server_api (mongoc_cmd_parts_t *parts, bool mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts, bson_iter_t *iter, - int max_wire_version, bson_error_t *error); bool mongoc_cmd_parts_set_read_concern (mongoc_cmd_parts_t *parts, const mongoc_read_concern_t *rc, - int max_wire_version, bson_error_t *error); bool mongoc_cmd_parts_set_write_concern (mongoc_cmd_parts_t *parts, const mongoc_write_concern_t *wc, - int max_wire_version, bson_error_t *error); bool mongoc_cmd_parts_append_read_write (mongoc_cmd_parts_t *parts, mongoc_read_write_opts_t *rw_opts, - int max_wire_version, bson_error_t *error); bool diff --git a/src/mongoc/mongoc-cmd.c b/src/mongoc/mongoc-cmd.c index 5c000b34..6ad74c43 100644 --- a/src/mongoc/mongoc-cmd.c +++ b/src/mongoc/mongoc-cmd.c @@ -33,6 +33,8 @@ mongoc_cmd_parts_init (mongoc_cmd_parts_t *parts, mongoc_query_flags_t user_query_flags, const bson_t *command_body) { + BSON_ASSERT_PARAM (client); + parts->body = command_body; parts->user_query_flags = user_query_flags; parts->read_prefs = NULL; @@ -52,6 +54,7 @@ mongoc_cmd_parts_init (mongoc_cmd_parts_t *parts, parts->assembled.db_name = db_name; parts->assembled.command = NULL; parts->assembled.query_flags = MONGOC_QUERY_NONE; + parts->assembled.op_msg_is_exhaust = false; parts->assembled.payload_identifier = NULL; parts->assembled.payload = NULL; parts->assembled.session = NULL; @@ -108,7 +111,6 @@ mongoc_cmd_parts_set_session (mongoc_cmd_parts_t *parts, bool mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts, bson_iter_t *iter, - int max_wire_version, bson_error_t *error) { mongoc_client_session_t *cs = NULL; @@ -124,23 +126,13 @@ mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts, BSON_ASSERT (!parts->assembled.command); while (bson_iter_next (iter)) { - if (BSON_ITER_IS_KEY (iter, "collation")) { - if (max_wire_version < WIRE_VERSION_COLLATION) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - RETURN (false); - } - - } else if (BSON_ITER_IS_KEY (iter, "writeConcern")) { + if (BSON_ITER_IS_KEY (iter, "writeConcern")) { wc = _mongoc_write_concern_new_from_iter (iter, error); if (!wc) { RETURN (false); } - if (!mongoc_cmd_parts_set_write_concern ( - parts, wc, max_wire_version, error)) { + if (!mongoc_cmd_parts_set_write_concern (parts, wc, error)) { mongoc_write_concern_destroy (wc); RETURN (false); } @@ -148,14 +140,6 @@ mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts, mongoc_write_concern_destroy (wc); continue; } else if (BSON_ITER_IS_KEY (iter, "readConcern")) { - if (max_wire_version < WIRE_VERSION_READ_CONCERN) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support readConcern"); - RETURN (false); - } - if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, @@ -213,7 +197,6 @@ mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts, bool mongoc_cmd_parts_set_read_concern (mongoc_cmd_parts_t *parts, const mongoc_read_concern_t *rc, - int max_wire_version, bson_error_t *error) { const char *command_name; @@ -238,18 +221,6 @@ mongoc_cmd_parts_set_read_concern (mongoc_cmd_parts_t *parts, RETURN (true); } - if (max_wire_version < WIRE_VERSION_READ_CONCERN) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "\"%s\" command does not support readConcern with " - "wire version %d, wire version %d is required", - command_name, - max_wire_version, - WIRE_VERSION_READ_CONCERN); - RETURN (false); - } - bson_destroy (&parts->read_concern_document); bson_copy_to (_mongoc_read_concern_get_bson ((mongoc_read_concern_t *) rc), &parts->read_concern_document); @@ -263,40 +234,24 @@ mongoc_cmd_parts_set_read_concern (mongoc_cmd_parts_t *parts, bool mongoc_cmd_parts_set_write_concern (mongoc_cmd_parts_t *parts, const mongoc_write_concern_t *wc, - int max_wire_version, bson_error_t *error) { - const char *command_name; - bool is_fam; - bool wc_allowed; - ENTRY; if (!wc) { RETURN (true); } - command_name = _mongoc_get_command_name (parts->body); + const char *const command_name = _mongoc_get_command_name (parts->body); if (!command_name) { OPTS_ERR (COMMAND_INVALID_ARG, "Empty command document"); } - is_fam = !strcasecmp (command_name, "findandmodify"); - - wc_allowed = - parts->is_write_command || - (is_fam && max_wire_version >= WIRE_VERSION_FAM_WRITE_CONCERN) || - (!is_fam && max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN); - - if (wc_allowed) { - parts->assembled.is_acknowledged = - mongoc_write_concern_is_acknowledged (wc); - bson_destroy (&parts->write_concern_document); - bson_copy_to ( - _mongoc_write_concern_get_bson ((mongoc_write_concern_t *) wc), - &parts->write_concern_document); - } + parts->assembled.is_acknowledged = mongoc_write_concern_is_acknowledged (wc); + bson_destroy (&parts->write_concern_document); + bson_copy_to (_mongoc_write_concern_get_bson ((mongoc_write_concern_t *) wc), + &parts->write_concern_document); RETURN (true); } @@ -324,7 +279,6 @@ mongoc_cmd_parts_set_write_concern (mongoc_cmd_parts_t *parts, bool mongoc_cmd_parts_append_read_write (mongoc_cmd_parts_t *parts, mongoc_read_write_opts_t *rw_opts, - int max_wire_version, bson_error_t *error) { ENTRY; @@ -333,11 +287,6 @@ mongoc_cmd_parts_append_read_write (mongoc_cmd_parts_t *parts, BSON_ASSERT (!parts->assembled.command); if (!bson_empty (&rw_opts->collation)) { - if (max_wire_version < WIRE_VERSION_COLLATION) { - OPTS_ERR (PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - } - if (!bson_append_document ( &parts->extra, "collation", 9, &rw_opts->collation)) { OPTS_ERR (COMMAND_INVALID_ARG, "'opts' with 'collation' is too large"); @@ -345,17 +294,12 @@ mongoc_cmd_parts_append_read_write (mongoc_cmd_parts_t *parts, } if (!mongoc_cmd_parts_set_write_concern ( - parts, rw_opts->writeConcern, max_wire_version, error)) { + parts, rw_opts->writeConcern, error)) { RETURN (false); } /* process explicit read concern */ if (!bson_empty (&rw_opts->readConcern)) { - if (max_wire_version < WIRE_VERSION_READ_CONCERN) { - OPTS_ERR (PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support readConcern"); - } - /* save readConcern for later, once we know about causal consistency */ bson_destroy (&parts->read_concern_document); bson_copy_to (&rw_opts->readConcern, &parts->read_concern_document); @@ -707,7 +651,7 @@ _allow_txn_number (const mongoc_cmd_parts_t *parts, return false; } - if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_WRITES) { + if (server_stream->retry_attempted) { return false; } @@ -740,7 +684,7 @@ _is_retryable_write (const mongoc_cmd_parts_t *parts, return false; } - if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_WRITES) { + if (server_stream->retry_attempted) { return false; } @@ -777,7 +721,7 @@ _is_retryable_read (const mongoc_cmd_parts_t *parts, return false; } - if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_READS) { + if (server_stream->retry_attempted) { return false; } @@ -896,7 +840,8 @@ mongoc_cmd_parts_assemble (mongoc_cmd_parts_t *parts, } if (mongoc_client_uses_server_api (parts->client) || - server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) { + mongoc_client_uses_loadbalanced (parts->client) || + server_stream->sd->max_wire_version >= WIRE_VERSION_MIN) { if (!bson_has_field (parts->body, "$db")) { BSON_APPEND_UTF8 (&parts->extra, "$db", parts->assembled.db_name); } @@ -1129,10 +1074,7 @@ _mongoc_cmd_append_payload_as_array (const mongoc_cmd_t *cmd, bson_t *out) bson_t doc; const uint8_t *pos; const char *field_name; - bson_t bson; - char str[16]; - const char *key; - uint32_t i; + bson_array_builder_t *bson; BSON_ASSERT (cmd->payload && cmd->payload_size); @@ -1140,22 +1082,19 @@ _mongoc_cmd_append_payload_as_array (const mongoc_cmd_t *cmd, bson_t *out) * "update", or "delete" command. */ field_name = _mongoc_get_documents_field_name (cmd->command_name); BSON_ASSERT (field_name); - BSON_ASSERT (BSON_APPEND_ARRAY_BEGIN (out, field_name, &bson)); + BSON_ASSERT (BSON_APPEND_ARRAY_BUILDER_BEGIN (out, field_name, &bson)); pos = cmd->payload; - i = 0; while (pos < cmd->payload + cmd->payload_size) { memcpy (&doc_len, pos, sizeof (doc_len)); doc_len = BSON_UINT32_FROM_LE (doc_len); BSON_ASSERT (bson_init_static (&doc, pos, (size_t) doc_len)); - bson_uint32_to_string (i, &key, str, sizeof (str)); - BSON_APPEND_DOCUMENT (&bson, key, &doc); + bson_array_builder_append_document (bson, &doc); pos += doc_len; - i++; } - bson_append_array_end (out, &bson); + bson_append_array_builder_end (out, bson); } /*-------------------------------------------------------------------------- diff --git a/src/mongoc/mongoc-collection.c b/src/mongoc/mongoc-collection.c index c668b46f..5dc87be4 100644 --- a/src/mongoc/mongoc-collection.c +++ b/src/mongoc/mongoc-collection.c @@ -41,6 +41,8 @@ #include "mongoc-error-private.h" #include "mongoc-database-private.h" +#include + #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "collection" @@ -57,7 +59,7 @@ _mongoc_collection_write_command_execute ( ENTRY; server_stream = mongoc_cluster_stream_for_writes ( - &collection->client->cluster, cs, NULL, &result->error); + &collection->client->cluster, cs, NULL, NULL, &result->error); if (!server_stream) { /* result->error has been filled out */ @@ -95,6 +97,7 @@ _mongoc_collection_write_command_execute_idl ( server_stream = mongoc_cluster_stream_for_writes (&collection->client->cluster, crud->client_session, + NULL, &reply, &result->error); @@ -750,27 +753,22 @@ mongoc_collection_count_with_opts ( bool success; bson_t reply; bson_t cmd = BSON_INITIALIZER; - bson_t q; ENTRY; BSON_ASSERT_PARAM (collection); - bson_append_utf8 ( - &cmd, "count", 5, collection->collection, collection->collectionlen); - if (query) { - bson_append_document (&cmd, "query", 5, query); - } else { - bson_init (&q); - bson_append_document (&cmd, "query", 5, &q); - bson_destroy (&q); - } - if (limit) { - bson_append_int64 (&cmd, "limit", 5, limit); - } - if (skip) { - bson_append_int64 (&cmd, "skip", 4, skip); - } + bsonBuildAppend ( + cmd, + kv ("count", + utf8_w_len (collection->collection, collection->collectionlen)), + kv ("query", + if (query, // If we have a query, + then (bson (*query)), // Copy it + else (doc ()))), // Otherwise, add an empty doc + if (limit, then (kv ("limit", int64 (limit)))), + if (skip, then (kv ("skip", int64 (skip))))); + success = _mongoc_client_command_with_opts (collection->client, collection->db, @@ -817,13 +815,8 @@ mongoc_collection_estimated_document_count ( BSON_ASSERT_PARAM (coll); - server_stream = - mongoc_cluster_stream_for_reads (&coll->client->cluster, - read_prefs, - NULL, - reply, - /* Not aggregate-with-write */ false, - error); + server_stream = mongoc_cluster_stream_for_reads ( + &coll->client->cluster, read_prefs, NULL, NULL, reply, error); if (opts && bson_has_field (opts, "sessionId")) { bson_set_error (error, @@ -883,52 +876,49 @@ mongoc_collection_estimated_document_count ( static void _make_aggregate_for_count (const mongoc_collection_t *coll, const bson_t *filter, - const bson_t *opts, + mongoc_count_document_opts_t *opts, bson_t *out) { - bson_iter_t iter; - bson_t pipeline; + bson_array_builder_t *pipeline; bson_t match_stage; bson_t group_stage; bson_t group_stage_doc; bson_t sum; bson_t empty; - const char *keys[] = {"0", "1", "2", "3"}; - int key = 0; bson_init (out); bson_append_utf8 ( out, "aggregate", 9, coll->collection, coll->collectionlen); bson_append_document_begin (out, "cursor", 6, &empty); bson_append_document_end (out, &empty); - bson_append_array_begin (out, "pipeline", 8, &pipeline); + bson_append_array_builder_begin (out, "pipeline", 8, &pipeline); - bson_append_document_begin (&pipeline, keys[key++], 1, &match_stage); + bson_array_builder_append_document_begin (pipeline, &match_stage); bson_append_document (&match_stage, "$match", 6, filter); - bson_append_document_end (&pipeline, &match_stage); - /* if @opts includes "skip", or "count", append $skip and $count stages to + bson_array_builder_append_document_end (pipeline, &match_stage); + /* if @opts includes "skip", or "limit", append $skip and $limit stages to * the aggregate pipeline. */ - if (opts && bson_iter_init_find (&iter, opts, "skip")) { + if (opts->skip.value_type != BSON_TYPE_EOD) { bson_t skip_stage; - bson_append_document_begin (&pipeline, keys[key++], 1, &skip_stage); - bson_append_value (&skip_stage, "$skip", 5, bson_iter_value (&iter)); - bson_append_document_end (&pipeline, &skip_stage); + bson_array_builder_append_document_begin (pipeline, &skip_stage); + bson_append_value (&skip_stage, "$skip", 5, &opts->skip); + bson_array_builder_append_document_end (pipeline, &skip_stage); } - if (opts && bson_iter_init_find (&iter, opts, "limit")) { + if (opts->limit.value_type != BSON_TYPE_EOD) { bson_t limit_stage; - bson_append_document_begin (&pipeline, keys[key++], 1, &limit_stage); - bson_append_value (&limit_stage, "$limit", 6, bson_iter_value (&iter)); - bson_append_document_end (&pipeline, &limit_stage); + bson_array_builder_append_document_begin (pipeline, &limit_stage); + bson_append_value (&limit_stage, "$limit", 6, &opts->limit); + bson_array_builder_append_document_end (pipeline, &limit_stage); } - bson_append_document_begin (&pipeline, keys[key], 1, &group_stage); + bson_array_builder_append_document_begin (pipeline, &group_stage); bson_append_document_begin (&group_stage, "$group", 6, &group_stage_doc); bson_append_int32 (&group_stage_doc, "_id", 3, 1); bson_append_document_begin (&group_stage_doc, "n", 1, &sum); bson_append_int32 (&sum, "$sum", 4, 1); bson_append_document_end (&group_stage_doc, &sum); bson_append_document_end (&group_stage, &group_stage_doc); - bson_append_document_end (&pipeline, &group_stage); - bson_append_array_end (out, &pipeline); + bson_array_builder_append_document_end (pipeline, &group_stage); + bson_append_array_builder_end (out, pipeline); } @@ -954,11 +944,18 @@ mongoc_collection_count_documents (mongoc_collection_t *coll, BSON_ASSERT_PARAM (coll); BSON_ASSERT_PARAM (filter); - _make_aggregate_for_count (coll, filter, opts, &aggregate_cmd); + // Parse options to validate. + mongoc_count_document_opts_t cd_opts; + if (!_mongoc_count_document_opts_parse ( + coll->client, opts, &cd_opts, error)) { + GOTO (done); + } + + _make_aggregate_for_count (coll, filter, &cd_opts, &aggregate_cmd); bson_init (&aggregate_opts); if (opts) { - bson_copy_to_excluding_noinit ( - opts, &aggregate_opts, "skip", "limit", NULL); + bsonBuildAppend (aggregate_opts, + insert (*opts, not(key ("skip", "limit")))); } ret = mongoc_collection_read_command_with_opts ( @@ -994,6 +991,7 @@ mongoc_collection_count_documents (mongoc_collection_t *coll, } done: + _mongoc_count_document_opts_cleanup (&cd_opts); if (cursor) { mongoc_cursor_destroy (cursor); } @@ -1063,10 +1061,8 @@ drop_with_opts_with_encryptedFields (mongoc_collection_t *collection, bson_error_t *error) { char *escName = NULL; - char *eccName = NULL; char *ecocName = NULL; mongoc_collection_t *escCollection = NULL; - mongoc_collection_t *eccCollection = NULL; mongoc_collection_t *ecocCollection = NULL; bool ok = false; const char *name = mongoc_collection_get_name (collection); @@ -1095,23 +1091,6 @@ drop_with_opts_with_encryptedFields (mongoc_collection_t *collection, } } - /* Drop ECC collection. */ - eccName = _mongoc_get_encryptedField_state_collection ( - encryptedFields, name, "ecc", error); - if (!eccName) { - goto fail; - } - - eccCollection = mongoc_client_get_collection ( - collection->client, collection->db, eccName); - if (!drop_with_opts (eccCollection, NULL /* opts */, error)) { - if (error->code == MONGOC_SERVER_ERR_NS_NOT_FOUND) { - memset (error, 0, sizeof (bson_error_t)); - } else { - goto fail; - } - } - /* Drop ECOC collection. */ ecocName = _mongoc_get_encryptedField_state_collection ( encryptedFields, name, "ecoc", error); @@ -1142,8 +1121,6 @@ drop_with_opts_with_encryptedFields (mongoc_collection_t *collection, fail: mongoc_collection_destroy (ecocCollection); bson_free (ecocName); - mongoc_collection_destroy (eccCollection); - bson_free (eccName); mongoc_collection_destroy (escCollection); bson_free (escName); return ok; @@ -1154,55 +1131,67 @@ mongoc_collection_drop_with_opts (mongoc_collection_t *collection, const bson_t *opts, bson_error_t *error) { - bson_iter_t iter; + // The encryptedFields for the collection. bson_t encryptedFields = BSON_INITIALIZER; - - if (opts && bson_iter_init_find (&iter, opts, "encryptedFields")) { - if (!_mongoc_iter_document_as_bson (&iter, &encryptedFields, error)) { - return false; - } + bson_t opts_without_encryptedFields = BSON_INITIALIZER; + bool okay = false; + + // Try to find the encryptedFields from the collection options or from the + // encryptedFieldsMap. + if (!_mongoc_get_collection_encryptedFields ( + collection->client, + collection->db, + mongoc_collection_get_name (collection), + opts, + true /* checkEncryptedFieldsMap */, + &encryptedFields, + error)) { + goto done; } if (bson_empty (&encryptedFields)) { - if (!_mongoc_get_encryptedFields_from_map ( - collection->client, - collection->db, - mongoc_collection_get_name (collection), - &encryptedFields, - error)) { - return false; + // We didn't find the encryptedFields (yet) + if (collection->client->topology->encrypted_fields_map != NULL) { + // but we can ask the server for them: + if (!_mongoc_get_encryptedFields_from_server ( + collection->client, + collection->db, + mongoc_collection_get_name (collection), + &encryptedFields, + error)) { + goto done; + } } } - if (bson_empty (&encryptedFields) && - collection->client->topology->encrypted_fields_map != NULL) { - if (!_mongoc_get_encryptedFields_from_server ( - collection->client, - collection->db, - mongoc_collection_get_name (collection), - &encryptedFields, - error)) { - return false; - } + if (bson_empty (&encryptedFields)) { + // There are no encryptedFields with this collection, so we can just do a + // regular drop + okay = drop_with_opts (collection, opts, error); + goto done; + } + + // We've found the encryptedFields, so we need to do something different + // to drop this collection: + bsonBuildAppend ( + opts_without_encryptedFields, + if (opts, then (insert (*opts, not(key ("encryptedFields")))))); + if (bsonBuildError) { + bson_set_error (error, + MONGOC_ERROR_BSON, + MONGOC_ERROR_BSON_INVALID, + "Error while updating drop options: %s", + bsonBuildError); + goto done; } - if (!bson_empty (&encryptedFields)) { - bson_t opts_without_encryptedFields = BSON_INITIALIZER; - - if (opts) { - bson_copy_to_excluding_noinit ( - opts, &opts_without_encryptedFields, "encryptedFields", NULL); - } - - bool ret = drop_with_opts_with_encryptedFields ( - collection, &opts_without_encryptedFields, &encryptedFields, error); + okay = drop_with_opts_with_encryptedFields ( + collection, &opts_without_encryptedFields, &encryptedFields, error); - bson_destroy (&opts_without_encryptedFields); - bson_destroy (&encryptedFields); - return ret; - } - - return drop_with_opts (collection, opts, error); +done: + bson_destroy (&opts_without_encryptedFields); + bson_destroy (&encryptedFields); + return okay; } @@ -1414,7 +1403,7 @@ _mongoc_collection_create_index_if_not_exists (mongoc_collection_t *collection, } bson_iter_document (&iter, &data_len, &data); - bson_init_static (&inner_doc, data, data_len); + BSON_ASSERT (bson_init_static (&inner_doc, data, data_len)); if (_mongoc_collection_index_keys_equal (keys, &inner_doc)) { index_exists = true; @@ -1492,7 +1481,7 @@ mongoc_collection_create_index_with_opts (mongoc_collection_t *collection, const mongoc_index_opt_geo_t *def_geo; const char *name; bson_t cmd = BSON_INITIALIZER; - bson_t ar; + bson_array_builder_t *ar; bson_t doc; bson_t storage_doc; bson_t wt_doc; @@ -1502,7 +1491,6 @@ mongoc_collection_create_index_with_opts (mongoc_collection_t *collection, char *alloc_name = NULL; bool ret = false; bool reply_initialized = false; - bool has_collation = false; mongoc_server_stream_t *server_stream = NULL; mongoc_cluster_t *cluster; @@ -1551,8 +1539,8 @@ mongoc_collection_create_index_with_opts (mongoc_collection_t *collection, */ BSON_ASSERT ( BSON_APPEND_UTF8 (&cmd, "createIndexes", collection->collection)); - bson_append_array_begin (&cmd, "indexes", 7, &ar); - bson_append_document_begin (&ar, "0", 1, &doc); + bson_append_array_builder_begin (&cmd, "indexes", 7, &ar); + bson_array_builder_append_document_begin (ar, &doc); BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "key", keys)); BSON_ASSERT (BSON_APPEND_UTF8 (&doc, "name", name)); if (opt->background) { @@ -1591,7 +1579,6 @@ mongoc_collection_create_index_with_opts (mongoc_collection_t *collection, } if (opt->collation) { BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "collation", opt->collation)); - has_collation = true; } if (opt->geo_options) { geo_opt = opt->geo_options; @@ -1635,30 +1622,19 @@ mongoc_collection_create_index_with_opts (mongoc_collection_t *collection, } } - bson_append_document_end (&ar, &doc); - bson_append_array_end (&cmd, &ar); + bson_array_builder_append_document_end (ar, &doc); + bson_append_array_builder_end (&cmd, ar); server_stream = mongoc_cluster_stream_for_writes ( - &collection->client->cluster, parsed.client_session, reply, error); + &collection->client->cluster, parsed.client_session, NULL, reply, error); if (!server_stream) { reply_initialized = true; GOTO (done); } - if (!mongoc_cmd_parts_set_write_concern (&parts, - parsed.writeConcern, - server_stream->sd->max_wire_version, - error)) { - GOTO (done); - } - - if (has_collation && - server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); + if (!mongoc_cmd_parts_set_write_concern ( + &parts, parsed.writeConcern, error)) { GOTO (done); } @@ -2270,6 +2246,7 @@ _mongoc_collection_update_or_replace (mongoc_collection_t *collection, server_stream = mongoc_cluster_stream_for_writes (&collection->client->cluster, update_opts->crud.client_session, + NULL, reply, error); @@ -2280,14 +2257,6 @@ _mongoc_collection_update_or_replace (mongoc_collection_t *collection, } if (!bson_empty0 (array_filters)) { - if (server_stream->sd->max_wire_version < WIRE_VERSION_ARRAY_FILTERS) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support array filters"); - GOTO (done); - } - if (!mongoc_write_concern_is_acknowledged ( update_opts->crud.writeConcern)) { bson_set_error (error, @@ -3371,8 +3340,8 @@ mongoc_collection_create_bulk_operation_with_opts ( * If @reply is not NULL, then the result document will be placed * in reply and should be released with bson_destroy(). * - * See http://docs.mongodb.org/manual/reference/command/findAndModify/ - * for more information. + * See for more information: + * https://www.mongodb.com/docs/manual/reference/command/findAndModify/ * * Returns: * true on success; false on failure. @@ -3429,7 +3398,7 @@ mongoc_collection_find_and_modify_with_opts ( } server_stream = mongoc_cluster_stream_for_writes ( - cluster, appended_opts.client_session, &ss_reply, error); + cluster, appended_opts.client_session, NULL, &ss_reply, error); if (!server_stream) { bson_concat (reply_ptr, &ss_reply); @@ -3497,9 +3466,7 @@ mongoc_collection_find_and_modify_with_opts ( write_concern = appended_opts.writeConcern; } /* inherit write concern from collection if not in transaction */ - else if (server_stream->sd->max_wire_version >= - WIRE_VERSION_FAM_WRITE_CONCERN && - !_mongoc_client_session_in_txn (parts.assembled.session)) { + else if (!_mongoc_client_session_in_txn (parts.assembled.session)) { if (!mongoc_write_concern_is_valid (collection->write_concern)) { bson_set_error (error, MONGOC_ERROR_COMMAND, @@ -3540,17 +3507,14 @@ mongoc_collection_find_and_modify_with_opts ( /* Append any remaining unparsed options set via * mongoc_find_and_modify_opts_append to the command part. */ if (bson_iter_init (&iter, &appended_opts.extra)) { - bool ok = mongoc_cmd_parts_append_opts ( - &parts, &iter, server_stream->sd->max_wire_version, error); - if (!ok) { + if (!mongoc_cmd_parts_append_opts (&parts, &iter, error)) { GOTO (done); } } /* An empty write concern amounts to a no-op, so there's no need to guard * against it. */ - if (!mongoc_cmd_parts_set_write_concern ( - &parts, write_concern, server_stream->sd->max_wire_version, error)) { + if (!mongoc_cmd_parts_set_write_concern (&parts, write_concern, error)) { GOTO (done); } @@ -3571,6 +3535,14 @@ mongoc_collection_find_and_modify_with_opts ( &txn_number_iter, ++parts.assembled.session->server_session->txn_number); } + + // Store the original error and reply if needed. + struct { + bson_t reply; + bson_error_t error; + bool set; + } original_error = {.reply = {0}, .error = {0}, .set = false}; + retry: bson_destroy (reply_ptr); ret = mongoc_cluster_run_command_monitored ( @@ -3578,7 +3550,7 @@ mongoc_collection_find_and_modify_with_opts ( if (parts.is_retryable_write) { _mongoc_write_error_handle_labels ( - ret, error, reply_ptr, server_stream->sd->max_wire_version); + ret, error, reply_ptr, server_stream->sd); } if (is_retryable) { @@ -3596,16 +3568,54 @@ mongoc_collection_find_and_modify_with_opts ( /* each write command may be retried at most once */ is_retryable = false; - retry_server_stream = mongoc_cluster_stream_for_writes ( - cluster, parts.assembled.session, NULL /* reply */, &ignored_error); - if (retry_server_stream && retry_server_stream->sd->max_wire_version >= - WIRE_VERSION_RETRY_WRITES) { + { + mongoc_deprioritized_servers_t *const ds = + mongoc_deprioritized_servers_new (); + + mongoc_deprioritized_servers_add_if_sharded ( + ds, server_stream->topology_type, server_stream->sd); + + retry_server_stream = + mongoc_cluster_stream_for_writes (cluster, + parts.assembled.session, + ds, + NULL /* reply */, + &ignored_error); + + mongoc_deprioritized_servers_destroy (ds); + } + + if (retry_server_stream) { parts.assembled.server_stream = retry_server_stream; + { + // Store the original error and reply before retry. + BSON_ASSERT (!original_error.set); // Retry only happens once. + original_error.set = true; + bson_copy_to (reply_ptr, &original_error.reply); + if (error) { + original_error.error = *error; + } + } GOTO (retry); } } + // If a retry attempt fails with an error labeled NoWritesPerformed, + // drivers MUST return the original error. + if (original_error.set && + mongoc_error_has_label (reply_ptr, "NoWritesPerformed")) { + if (error) { + *error = original_error.error; + } + bson_destroy (reply_ptr); + bson_copy_to (&original_error.reply, reply_ptr); + } + + if (original_error.set) { + bson_destroy (&original_error.reply); + } + if (bson_iter_init_find (&iter, reply_ptr, "writeConcernError") && BSON_ITER_HOLDS_DOCUMENT (&iter)) { const char *errmsg = NULL; @@ -3664,8 +3674,8 @@ mongoc_collection_find_and_modify_with_opts ( * If @_new is true, then the new version of the document is returned * instead of the old document. * - * See http://docs.mongodb.org/manual/reference/command/findAndModify/ - * for more information. + * See for more information: + * https://www.mongodb.com/docs/manual/reference/command/findAndModify/ * * Returns: * true on success; false on failure. @@ -3731,3 +3741,135 @@ mongoc_collection_watch (const mongoc_collection_t *coll, { return _mongoc_change_stream_new_from_collection (coll, pipeline, opts); } + +struct _mongoc_index_model_t { + bson_t *keys; + bson_t *opts; +}; + +mongoc_index_model_t * +mongoc_index_model_new (const bson_t *keys, const bson_t *opts) +{ + BSON_ASSERT_PARAM (keys); + // `opts` may be NULL. + + mongoc_index_model_t *im = bson_malloc (sizeof (mongoc_index_model_t)); + im->keys = bson_copy (keys); + im->opts = opts ? bson_copy (opts) : NULL; + return im; +} + +void +mongoc_index_model_destroy (mongoc_index_model_t *im) +{ + if (!im) { + return; + } + bson_destroy (im->keys); + bson_destroy (im->opts); + bson_free (im); +} + +bool +mongoc_collection_create_indexes_with_opts (mongoc_collection_t *collection, + mongoc_index_model_t *const *models, + size_t n_models, + const bson_t *opts, + bson_t *reply, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (collection); + BSON_ASSERT_PARAM (models); + // `opts` may be NULL. + // `reply` may be NULL. + // `error` may be NULL. + bson_t reply_local = BSON_INITIALIZER; + bson_t *reply_ptr; + mongoc_server_stream_t *server_stream = NULL; + bool ok = false; + bson_t cmd = BSON_INITIALIZER; + + reply_ptr = reply ? reply : &reply_local; + // Always initialize `reply` if set. Caller is expected to `bson_destroy + // (reply)`. + bson_init (reply_ptr); + + // Check for commitQuorum option. + if (opts && bson_has_field (opts, "commitQuorum")) { + server_stream = + mongoc_cluster_stream_for_writes (&collection->client->cluster, + NULL /* mongoc_client_session_t */, + NULL /* deprioritized servers */, + reply_ptr, + error); + if (server_stream->sd->max_wire_version < WIRE_VERSION_4_4) { + // Raise an error required by the specification: + // "Drivers MUST manually raise an error if this option is specified + // when creating an index on a pre 4.4 server." + bson_set_error ( + error, + MONGOC_ERROR_COMMAND, + MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, + "The selected server does not support the commitQuorum option"); + GOTO (fail); + } + } + + // Build the createIndexes command. + BSON_ASSERT ( + BSON_APPEND_UTF8 (&cmd, "createIndexes", collection->collection)); + bson_array_builder_t *indexes; + BSON_ASSERT (BSON_APPEND_ARRAY_BUILDER_BEGIN (&cmd, "indexes", &indexes)); + for (uint32_t idx = 0; idx < n_models; idx++) { + /* + Append a document of this form: + : { + key: { + , + , + ... + }, + name: , + , + , + ... + }, + */ + + bson_t index; + BSON_ASSERT (bson_array_builder_append_document_begin (indexes, &index)); + BSON_ASSERT (BSON_APPEND_DOCUMENT (&index, "key", models[idx]->keys)); + bson_iter_t name_iter; + if (models[idx]->opts && + bson_iter_init_find (&name_iter, models[idx]->opts, "name")) { + // `name` was specified as an index option. + } else { + // No `name` was specified. Create index `name` from keys. + char *name = + mongoc_collection_keys_to_index_string (models[idx]->keys); + BSON_ASSERT (name); + BSON_ASSERT (BSON_APPEND_UTF8 (&index, "name", name)); + bson_free (name); + } + + if (models[idx]->opts) { + BSON_ASSERT (bson_concat (&index, models[idx]->opts)); + } + BSON_ASSERT (bson_array_builder_append_document_end (indexes, &index)); + } + BSON_ASSERT (bson_append_array_builder_end (&cmd, indexes)); + + ok = mongoc_client_command_with_opts (collection->client, + collection->db, + &cmd, + NULL /* read_prefs */, + opts, + reply_ptr, + error); + +fail: + mongoc_server_stream_cleanup (server_stream); + bson_destroy (&cmd); + bson_destroy (&reply_local); + return ok; +} diff --git a/src/mongoc/mongoc-collection.h b/src/mongoc/mongoc-collection.h index a36c5ace..89ff3e40 100644 --- a/src/mongoc/mongoc-collection.h +++ b/src/mongoc/mongoc-collection.h @@ -156,6 +156,23 @@ MONGOC_EXPORT (mongoc_cursor_t *) mongoc_collection_find_indexes_with_opts (mongoc_collection_t *collection, const bson_t *opts) BSON_GNUC_WARN_UNUSED_RESULT; + +typedef struct _mongoc_index_model_t mongoc_index_model_t; + +MONGOC_EXPORT (mongoc_index_model_t *) +mongoc_index_model_new (const bson_t *keys, const bson_t *opts); + +MONGOC_EXPORT (void) mongoc_index_model_destroy (mongoc_index_model_t *model); + +MONGOC_EXPORT (bool) +mongoc_collection_create_indexes_with_opts (mongoc_collection_t *collection, + mongoc_index_model_t *const *models, + size_t n_models, + const bson_t *opts, + bson_t *reply, + bson_error_t *error); + + MONGOC_EXPORT (mongoc_cursor_t *) mongoc_collection_find (mongoc_collection_t *collection, mongoc_query_flags_t flags, diff --git a/src/mongoc/mongoc-compression.c b/src/mongoc/mongoc-compression.c index 371ba142..f1a50b7e 100644 --- a/src/mongoc/mongoc-compression.c +++ b/src/mongoc/mongoc-compression.c @@ -48,7 +48,8 @@ mongoc_compressor_max_compressed_length (int32_t compressor_id, size_t len) #ifdef MONGOC_ENABLE_COMPRESSION_ZLIB case MONGOC_COMPRESSOR_ZLIB_ID: - return compressBound (len); + BSON_ASSERT (bson_in_range_unsigned (unsigned_long, len)); + return compressBound ((unsigned long) len); break; #endif @@ -173,12 +174,11 @@ mongoc_uncompress (int32_t compressor_id, case MONGOC_COMPRESSOR_ZLIB_ID: { #ifdef MONGOC_ENABLE_COMPRESSION_ZLIB - int ok; - - ok = uncompress (uncompressed, - (unsigned long *) uncompressed_len, - compressed, - compressed_len); + BSON_ASSERT (bson_in_range_unsigned (unsigned_long, compressed_len)); + const int ok = uncompress (uncompressed, + (unsigned long *) uncompressed_len, + compressed, + (unsigned long) compressed_len); return ok == Z_OK; #else @@ -193,11 +193,10 @@ mongoc_uncompress (int32_t compressor_id, #ifdef MONGOC_ENABLE_COMPRESSION_ZSTD int ok; - ok = - ZSTD_decompress ((void *) uncompressed, - *uncompressed_len, - (const void *) compressed, - compressed_len); + ok = ZSTD_decompress ((void *) uncompressed, + *uncompressed_len, + (const void *) compressed, + compressed_len); if (!ZSTD_isError (ok)) { *uncompressed_len = ok; @@ -249,10 +248,11 @@ mongoc_compress (int32_t compressor_id, case MONGOC_COMPRESSOR_ZLIB_ID: #ifdef MONGOC_ENABLE_COMPRESSION_ZLIB + BSON_ASSERT (bson_in_range_unsigned (unsigned_long, uncompressed_len)); return compress2 ((unsigned char *) compressed, (unsigned long *) compressed_len, (unsigned char *) uncompressed, - uncompressed_len, + (unsigned long) uncompressed_len, compression_level) == Z_OK; #else MONGOC_ERROR ("Client attempting to use compress with zlib, but zlib " diff --git a/src/mongoc/mongoc-config.h b/src/mongoc/mongoc-config.h index a8c55c53..6e275cc2 100644 --- a/src/mongoc/mongoc-config.h +++ b/src/mongoc/mongoc-config.h @@ -18,18 +18,6 @@ #ifndef MONGOC_CONFIG_H #define MONGOC_CONFIG_H -#define MONGOC_TRACE 0 - -enum { - /** - * @brief Compile-time constant determining whether the mongoc library was - * compiled with tracing enabled. - * - * Can be controlled with the 'ENABLE_TRACING" configure-time boolean option - */ - MONGOC_TRACE_ENABLED = MONGOC_TRACE -}; - /* R packages should be portable */ #define MONGOC_CC "" #define MONGOC_USER_SET_CFLAGS "" @@ -244,4 +232,11 @@ enum { #endif #endif +#define MONGOC_TRACE 0 +#define MONGOC_ENABLE_SRV 1 +enum { + MONGOC_TRACE_ENABLED = MONGOC_TRACE, + MONGOC_SRV_ENABLED = MONGOC_ENABLE_SRV, +}; + #endif /* MONGOC_CONFIG_H */ diff --git a/src/mongoc/mongoc-counters-private.h b/src/mongoc/mongoc-counters-private.h index ddd4d495..736a56ca 100644 --- a/src/mongoc/mongoc-counters-private.h +++ b/src/mongoc/mongoc-counters-private.h @@ -28,6 +28,7 @@ #include #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ defined(__OpenBSD__) +#include #include #include #include @@ -97,9 +98,8 @@ static BSON_INLINE unsigned _mongoc_sched_getcpu (void) { volatile uint32_t rax, rdx, rcx; - __asm__ volatile("rdtscp\n" : "=a"(rax), "=d"(rdx), "=c"(rcx) : :); - unsigned node_id, core_id; - // node_id = (rcx & 0xFFF000)>>12; // node_id is unused + __asm__ volatile ("rdtscp\n" : "=a"(rax), "=d"(rdx), "=c"(rcx) : :); + unsigned core_id; core_id = rcx & 0xFFF; return core_id; } @@ -113,7 +113,7 @@ _mongoc_sched_getcpu (void) unsigned core_id; /* Get the current thread ID, not the core ID. * Getting the core ID requires privileged execution. */ - __asm__ volatile("mrs %x0, tpidrro_el0" : "=r"(tls)); + __asm__ volatile ("mrs %x0, tpidrro_el0" : "=r"(tls)); /* In ARM, only 8 cores are manageable. */ core_id = tls & 0x07u; return core_id; @@ -178,9 +178,23 @@ enum { bson_atomic_int64_exchange (counter, 0, bson_memory_order_seq_cst); \ } \ bson_atomic_thread_fence (); \ + } \ + static BSON_INLINE int32_t mongoc_counter_##ident##_count (void) \ + { \ + int32_t _sum = 0; \ + uint32_t _i; \ + for (_i = 0; _i < _mongoc_get_cpu_count (); _i++) { \ + const int64_t *counter = \ + &BSON_CONCAT (__mongoc_counter_, ident) \ + .cpus[_i] \ + .slots[BSON_CONCAT (COUNTER_, ident) % SLOTS_PER_CACHELINE]; \ + _sum += bson_atomic_int64_fetch (counter, bson_memory_order_seq_cst); \ + } \ + return _sum; \ } #include "mongoc-counters.defs" #undef COUNTER + #else /* when counters are disabled, these functions are no-ops */ #define COUNTER(ident, Category, Name, Description) \ @@ -195,6 +209,9 @@ enum { } \ static BSON_INLINE void mongoc_counter_##ident##_reset (void) \ { \ + } \ + static BSON_INLINE void mongoc_counter_##ident##_count (void) \ + { \ } #include "mongoc-counters.defs" #undef COUNTER diff --git a/src/mongoc/mongoc-counters.c b/src/mongoc/mongoc-counters.c index d6503fab..f8a6bdf7 100644 --- a/src/mongoc/mongoc-counters.c +++ b/src/mongoc/mongoc-counters.c @@ -24,6 +24,7 @@ #ifdef BSON_OS_UNIX #include #include +#include #endif #ifdef _MSC_VER @@ -111,7 +112,7 @@ mongoc_counters_calc_size (void) (n_cpu * n_groups * sizeof (mongoc_counter_slots_t))); #ifdef BSON_OS_UNIX - return BSON_MAX (getpagesize (), size); + return BSON_MAX (sysconf (_SC_PAGESIZE), size); #else return size; #endif @@ -180,15 +181,18 @@ mongoc_counters_alloc (size_t size) goto fail_noclean; } - /* - * NOTE: - * - * ftruncate() will cause reads to be zero. Therefore, we don't need to - * do write() of zeroes to initialize the shared memory area. - */ +#if defined(__APPLE__) + // macOS does not have posix_fallocate available. if (-1 == ftruncate (fd, size)) { goto fail_cleanup; } +#else + // Prefer posix_fallocate on Linux. posix_fallocate ensures that disk space + // is allocated. + if (0 != posix_fallocate (fd, 0, size)) { + goto fail_cleanup; + } +#endif // __APPLE__ mem = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { diff --git a/src/mongoc/mongoc-crypt-private.h b/src/mongoc/mongoc-crypt-private.h index c0f236dc..b9ac23b1 100644 --- a/src/mongoc/mongoc-crypt-private.h +++ b/src/mongoc/mongoc-crypt-private.h @@ -82,24 +82,39 @@ _mongoc_crypt_auto_decrypt (_mongoc_crypt_t *crypt, /* Perform explicit encryption. -- exactly one of keyid or keyaltname must be set, the other NULL, or an error is -returned. -- value_out is always initialized. -- query_type may be NULL. -- contention_factor may be NULL. -- may return false and set error. +Return false on error and sets `error`. */ bool -_mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt, - mongoc_collection_t *key_vault_coll, - const char *algorithm, - const bson_value_t *keyid, - char *keyaltname, - const char *query_type, - const int64_t *contention_factor, - const bson_value_t *value_in, - bson_value_t *value_out, - bson_error_t *error); +_mongoc_crypt_explicit_encrypt ( + _mongoc_crypt_t *crypt, + mongoc_collection_t *key_vault_coll, + const char *algorithm /* may be NULL */, + const bson_value_t *keyid /* may be NULL */, + const char *keyaltname /* may be NULL */, + const char *query_type /* may be NULL */, + const int64_t *contention_factor /* may be NULL */, + const bson_t *range_opts /* may be NULL */, + const bson_value_t *value_in, + bson_value_t *value_out, + bson_error_t *error); + +/* +Perform explicit encryption on an expression. +Return false on error and sets `error`. +*/ +bool +_mongoc_crypt_explicit_encrypt_expression ( + _mongoc_crypt_t *crypt, + mongoc_collection_t *key_vault_coll, + const char *algorithm /* may be NULL */, + const bson_value_t *keyid /* may be NULL */, + const char *keyaltname /* may be NULL */, + const char *query_type /* may be NULL */, + const int64_t *contention_factor /* may be NULL */, + const bson_t *range_opts /* may be NULL */, + const bson_t *expr_in, + bson_t *expr_out, + bson_error_t *error); /* Perform explicit decryption. diff --git a/src/mongoc/mongoc-crypt.c b/src/mongoc/mongoc-crypt.c index b954c474..847a75cf 100644 --- a/src/mongoc/mongoc-crypt.c +++ b/src/mongoc/mongoc-crypt.c @@ -29,6 +29,92 @@ #include "mongoc-ssl-private.h" #include "mongoc-cluster-aws-private.h" #include "mongoc-util-private.h" +#include "mongoc-http-private.h" +#include "mcd-azure.h" +#include "mcd-time.h" +#include "service-gcp.h" + +// `mcd_mapof_kmsid_to_tlsopts` maps a KMS ID (e.g. `aws` or `aws:myname`) to a +// `mongoc_ssl_opt_t`. The acryonym TLS is preferred over SSL for +// consistency with the CSE and URI specifications. +typedef struct { + mongoc_array_t entries; +} mcd_mapof_kmsid_to_tlsopts; + +typedef struct { + char *kmsid; + mongoc_ssl_opt_t tlsopts; +} mcd_mapof_kmsid_to_tlsopts_entry; + +mcd_mapof_kmsid_to_tlsopts * +mcd_mapof_kmsid_to_tlsopts_new (void) +{ + mcd_mapof_kmsid_to_tlsopts *k2t = + bson_malloc0 (sizeof (mcd_mapof_kmsid_to_tlsopts)); + _mongoc_array_init (&k2t->entries, + sizeof (mcd_mapof_kmsid_to_tlsopts_entry)); + return k2t; +} + +void +mcd_mapof_kmsid_to_tlsopts_destroy (mcd_mapof_kmsid_to_tlsopts *k2t) +{ + if (!k2t) { + return; + } + for (size_t i = 0; i < k2t->entries.len; i++) { + mcd_mapof_kmsid_to_tlsopts_entry *e = &_mongoc_array_index ( + &k2t->entries, mcd_mapof_kmsid_to_tlsopts_entry, i); + bson_free (e->kmsid); + _mongoc_ssl_opts_cleanup (&e->tlsopts, true /* free_internal */); + } + _mongoc_array_destroy (&k2t->entries); + bson_free (k2t); +} + +// `mcd_mapof_kmsid_to_tlsopts_insert` adds an entry into the map. +// `kmsid` and `tlsopts` are copied. +// No checking is done to prohibit duplicate entries. +void +mcd_mapof_kmsid_to_tlsopts_insert (mcd_mapof_kmsid_to_tlsopts *k2t, + const char *kmsid, + const mongoc_ssl_opt_t *tlsopts) +{ + BSON_ASSERT_PARAM (k2t); + BSON_ASSERT_PARAM (kmsid); + BSON_ASSERT_PARAM (tlsopts); + + mcd_mapof_kmsid_to_tlsopts_entry e = {.kmsid = bson_strdup (kmsid)}; + _mongoc_ssl_opts_copy_to (tlsopts, &e.tlsopts, true /* copy_internal */); + _mongoc_array_append_val (&k2t->entries, e); +} + +// `mcd_mapof_kmsid_to_tlsopts_get` returns the TLS options for a KMS ID, or +// NULL. +const mongoc_ssl_opt_t * +mcd_mapof_kmsid_to_tlsopts_get (const mcd_mapof_kmsid_to_tlsopts *k2t, + const char *kmsid) +{ + BSON_ASSERT_PARAM (k2t); + BSON_ASSERT_PARAM (kmsid); + + for (size_t i = 0; i < k2t->entries.len; i++) { + mcd_mapof_kmsid_to_tlsopts_entry *e = &_mongoc_array_index ( + &k2t->entries, mcd_mapof_kmsid_to_tlsopts_entry, i); + if (0 == strcmp (e->kmsid, kmsid)) { + return &e->tlsopts; + } + } + return NULL; +} + + +bool +mcd_mapof_kmsid_to_tlsopts_has (const mcd_mapof_kmsid_to_tlsopts *k2t, + const char *kmsid) +{ + return NULL != mcd_mapof_kmsid_to_tlsopts_get (k2t, kmsid); +} struct __mongoc_crypt_t { mongocrypt_t *handle; @@ -36,11 +122,19 @@ struct __mongoc_crypt_t { mongoc_ssl_opt_t aws_tls_opt; mongoc_ssl_opt_t azure_tls_opt; mongoc_ssl_opt_t gcp_tls_opt; + mcd_mapof_kmsid_to_tlsopts *kmsid_to_tlsopts; + /// The kmsProviders that were provided by the user when encryption was /// initiated. We need to remember this in case we need to load on-demand /// credentials. bson_t kms_providers; mc_kms_credentials_callback creds_cb; + + /// The most recently auto-acquired Azure token, on null if it was destroyed + /// or not yet acquired. + mcd_azure_access_token azure_token; + /// The time point at which the `azure_token` was acquired. + mcd_time_point azure_token_issued_at; }; static void @@ -222,6 +316,9 @@ _state_machine_new (_mongoc_crypt_t *crypt) void _state_machine_destroy (_state_machine_t *state_machine) { + if (!state_machine) { + return; + } mongocrypt_ctx_destroy (state_machine->ctx); bson_free (state_machine); } @@ -440,6 +537,15 @@ _get_stream (const char *endpoint, tls_stream = mongoc_stream_tls_new_with_hostname ( base_stream, host.host, &ssl_opt_copy, 1 /* client */); + if (!tls_stream) { + bson_set_error (error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "Failed to create TLS stream to: %s", + endpoint); + goto fail; + } + if (!mongoc_stream_tls_handshake_block ( tls_stream, host.host, connecttimeoutms, error)) { goto fail; @@ -469,9 +575,7 @@ _state_need_kms (_state_machine_t *state_machine, bson_error_t *error) mongocrypt_binary_t *http_req = NULL; mongocrypt_binary_t *http_reply = NULL; const char *endpoint; - uint32_t sockettimeout; - - sockettimeout = MONGOC_DEFAULT_SOCKETTIMEOUTMS; + const int32_t sockettimeout = MONGOC_DEFAULT_SOCKETTIMEOUTMS; kms_ctx = mongocrypt_ctx_next_kms_ctx (state_machine->ctx); while (kms_ctx) { mongoc_iovec_t iov; @@ -488,6 +592,10 @@ _state_need_kms (_state_machine_t *state_machine, bson_error_t *error) ssl_opt = &state_machine->crypt->azure_tls_opt; } else if (0 == strcmp ("gcp", provider)) { ssl_opt = &state_machine->crypt->gcp_tls_opt; + } else if (mcd_mapof_kmsid_to_tlsopts_has ( + state_machine->crypt->kmsid_to_tlsopts, provider)) { + ssl_opt = mcd_mapof_kmsid_to_tlsopts_get ( + state_machine->crypt->kmsid_to_tlsopts, provider); } else { ssl_opt = mongoc_ssl_opt_get_default (); } @@ -556,7 +664,10 @@ _state_need_kms (_state_machine_t *state_machine, bson_error_t *error) } mongocrypt_binary_destroy (http_reply); - http_reply = mongocrypt_binary_new_from_data (buf, read_ret); + + BSON_ASSERT (bson_in_range_signed (uint32_t, read_ret)); + http_reply = + mongocrypt_binary_new_from_data (buf, (uint32_t) read_ret); if (!mongocrypt_kms_ctx_feed (kms_ctx, http_reply)) { _kms_ctx_check_error (kms_ctx, error, true); goto fail; @@ -590,8 +701,8 @@ _state_need_kms (_state_machine_t *state_machine, bson_error_t *error) * * @param kms_providers The user-provided kmsProviders * @param error Output parameter for possible errors. - * @return true If 'aws' is present and an empty subdocument - * @return false Otherwise or on error + * @retval true If 'aws' is present and an empty subdocument + * @retval false Otherwise or on error */ static bool _needs_on_demand_aws_kms (bson_t const *kms_providers, bson_error_t *error) @@ -628,14 +739,43 @@ _needs_on_demand_aws_kms (bson_t const *kms_providers, bson_error_t *error) } } +/** + * @brief Check whether the given kmsProviders object requests automatic Azure + * credentials + * + * @param kmsprov The input kmsProviders that may have an "azure" property + * @param error An output error + * @retval true If success AND `kmsprov` requests automatic Azure credentials + * @retval false Otherwise. Check error->code for failure. + */ +static bool +_check_azure_kms_auto (const bson_t *kmsprov, bson_error_t *error) +{ + if (error) { + *error = (bson_error_t){0}; + } + + bson_iter_t iter; + if (!bson_iter_init_find (&iter, kmsprov, "azure")) { + return false; + } + + bson_t azure_subdoc; + if (!_mongoc_iter_document_as_bson (&iter, &azure_subdoc, error)) { + return false; + } + + return bson_empty (&azure_subdoc); +} + /** * @brief Attempt to load AWS credentials from the environment and insert them * into the given kmsProviders bson document on the "aws" property. * * @param out A kmsProviders object to update * @param error An error-out parameter - * @return true If there was no error and we successfully loaded credentials. - * @return false If there was an error while updating the BSON data or obtaining + * @retval true If there was no error and we successfully loaded credentials. + * @retval false If there was an error while updating the BSON data or obtaining * credentials. */ static bool @@ -666,6 +806,164 @@ _try_add_aws_from_env (bson_t *out, bson_error_t *error) return true; } +/** + * @brief Attempt to request a new Azure access token from the IMDS HTTP server + * + * @param out The token to populate. Must later be destroyed by the caller. + * @param error An output parameter to capture any errors + * @retval true Upon successfully obtaining and parsing a token + * @retval false If any error occurs. + */ +static bool +_request_new_azure_token (mcd_azure_access_token *out, bson_error_t *error) +{ + return mcd_azure_access_token_from_imds (out, + NULL, // Use the default host + 0, // Default port as well + NULL, // No extra headers + error); +} + +/** + * @brief Attempt to load an Azure access token from the environment and append + * them to the kmsProviders + * + * @param out A kmsProviders object to update + * @param error An error-out parameter + * @retval true If there was no error and we loaded credentials + * @retval false If there was an error obtaining or appending credentials + */ +static bool +_try_add_azure_from_env (_mongoc_crypt_t *crypt, + bson_t *out, + bson_error_t *error) +{ + if (crypt->azure_token.access_token) { + // The access-token is non-null, so we may have one cached. + mcd_time_point one_min_from_now = mcd_later (mcd_now (), mcd_minutes (1)); + mcd_time_point expires_at = mcd_later (crypt->azure_token_issued_at, + crypt->azure_token.expires_in); + if (mcd_time_compare (expires_at, one_min_from_now) >= 0) { + // The token is still valid for at least another minute + } else { + // The token will expire soon. Destroy it, and below we will below ask + // IMDS for a new one. + mcd_azure_access_token_destroy (&crypt->azure_token); + } + } + + if (crypt->azure_token.access_token == NULL) { + // There is no access token in our cache. + // Save the current time point as the "issue time" of the token, even + // though it will take some time for the HTTP request to hit the metadata + // server. This time is only used to track token expiry. IMDS gives us a + // number of seconds that the token will be valid relative to its issue + // time. Avoid reliance on system clocks by comparing the issue time to an + // abstract monotonic "now" + crypt->azure_token_issued_at = mcd_now (); + // Get the token: + if (!_request_new_azure_token (&crypt->azure_token, error)) { + return false; + } + } + + // Build the new KMS credentials + bson_t new_azure_creds = BSON_INITIALIZER; + const bool okay = BSON_APPEND_UTF8 (&new_azure_creds, + "accessToken", + crypt->azure_token.access_token) && + BSON_APPEND_DOCUMENT (out, "azure", &new_azure_creds); + bson_destroy (&new_azure_creds); + if (!okay) { + bson_set_error (error, + MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION, + MONGOC_ERROR_BSON_INVALID, + "Failed to build new 'azure' credentials"); + } + + return okay; +} + +/** + * @brief Check whether the given kmsProviders object requests automatic GCP + * credentials + * + * @param kmsprov The input kmsProviders that may have an "gcp" property + * @param error An output error + * @retval true If success AND `kmsprov` requests automatic GCP credentials + * @retval false Otherwise. Check error->code for failure. + */ +static bool +_check_gcp_kms_auto (const bson_t *kmsprov, bson_error_t *error) +{ + if (error) { + *error = (bson_error_t){0}; + } + + bson_iter_t iter; + if (!bson_iter_init_find (&iter, kmsprov, "gcp")) { + return false; + } + + bson_t gcp_subdoc; + if (!_mongoc_iter_document_as_bson (&iter, &gcp_subdoc, error)) { + return false; + } + + return bson_empty (&gcp_subdoc); +} + +/** + * @brief Attempt to request a new GCP access token from the HTTP server + * + * @param out The token to populate. Must later be destroyed by the caller. + * @param error An output parameter to capture any errors + * @retval true Upon successfully obtaining and parsing a token + * @retval false If any error occurs. + */ +static bool +_request_new_gcp_token (gcp_service_account_token *out, bson_error_t *error) +{ + return (gcp_access_token_from_gcp_server (out, NULL, 0, NULL, error)); +} + +/** + * @brief Attempt to load an GCP access token from the environment and append + * them to the kmsProviders + * + * @param out A kmsProviders object to update + * @param error An error-out parameter + * @retval true If there was no error and we loaded credentials + * @retval false If there was an error obtaining or appending credentials + */ +static bool +_try_add_gcp_from_env (bson_t *out, bson_error_t *error) +{ + // Not caching gcp tokens, so we will always request a new one from the gcp + // server. + gcp_service_account_token gcp_token; + if (!_request_new_gcp_token (&gcp_token, error)) { + return false; + } + + // Build the new KMS credentials + bson_t new_gcp_creds = BSON_INITIALIZER; + const bool okay = BSON_APPEND_UTF8 (&new_gcp_creds, + "accessToken", + gcp_token.access_token) && + BSON_APPEND_DOCUMENT (out, "gcp", &new_gcp_creds); + bson_destroy (&new_gcp_creds); + gcp_access_token_destroy (&gcp_token); + if (!okay) { + bson_set_error (error, + MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION, + MONGOC_ERROR_BSON_INVALID, + "Failed to build new 'gcp' credentials"); + } + + return okay; +} + static bool _state_need_kms_credentials (_state_machine_t *sm, bson_error_t *error) { @@ -707,6 +1005,38 @@ _state_need_kms_credentials (_state_machine_t *sm, bson_error_t *error) } } + // Whether the callback provided Azure credentials + const bool cb_provided_azure = bson_iter_init_find (&iter, &creds, "azure"); + // Whether the original kmsProviders requested auto-Azure credentials: + const bool orig_wants_auto_azure = + _check_azure_kms_auto (&sm->crypt->kms_providers, error); + if (error->code) { + // _check_azure_kms_auto failed + goto fail; + } + const bool wants_auto_azure = orig_wants_auto_azure && !cb_provided_azure; + if (wants_auto_azure) { + if (!_try_add_azure_from_env (sm->crypt, &creds, error)) { + goto fail; + } + } + + // Whether the callback provided GCP credentials + const bool cb_provided_gcp = bson_iter_init_find (&iter, &creds, "gcp"); + // Whether the original kmsProviders requested auto-GCP credentials: + const bool orig_wants_auto_gcp = + _check_gcp_kms_auto (&sm->crypt->kms_providers, error); + if (error->code) { + // _check_gcp_kms_auto failed + goto fail; + } + const bool wants_auto_gcp = orig_wants_auto_gcp && !cb_provided_gcp; + if (wants_auto_gcp) { + if (!_try_add_gcp_from_env (&creds, error)) { + goto fail; + } + } + // Now actually send that data to libmongocrypt mongocrypt_binary_t *const def = mongocrypt_binary_new_from_data ( (uint8_t *) bson_get_data (&creds), creds.len); @@ -884,6 +1214,10 @@ _parse_one_tls_opts (bson_iter_t *iter, continue; } + if (0 == bson_strcasecmp (key, MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK)) { + continue; + } + bson_set_error ( error, MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION, @@ -1012,6 +1346,29 @@ _parse_all_tls_opts (_mongoc_crypt_t *crypt, continue; } + const char *colon_pos = strstr (key, ":"); + if (colon_pos != NULL) { + // Parse TLS options for a named KMS provider. + if (mcd_mapof_kmsid_to_tlsopts_has (crypt->kmsid_to_tlsopts, key)) { + bson_set_error (error, + MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION, + MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, + "Error parsing duplicate TLS options for %s", + key); + goto fail; + } + + mongoc_ssl_opt_t tlsopts = {0}; + if (!_parse_one_tls_opts (&iter, &tlsopts, error)) { + _mongoc_ssl_opts_cleanup (&tlsopts, true /* free_internal */); + goto fail; + } + mcd_mapof_kmsid_to_tlsopts_insert ( + crypt->kmsid_to_tlsopts, key, &tlsopts); + _mongoc_ssl_opts_cleanup (&tlsopts, true /* free_internal */); + continue; + } + bson_set_error (error, MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION, MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, @@ -1079,6 +1436,7 @@ _mongoc_crypt_new (const bson_t *kms_providers, /* Create the handle to libmongocrypt. */ crypt = bson_malloc0 (sizeof (*crypt)); + crypt->kmsid_to_tlsopts = mcd_mapof_kmsid_to_tlsopts_new (); crypt->handle = mongocrypt_new (); // Stash away a copy of the user's kmsProviders in case we need to lazily @@ -1200,6 +1558,8 @@ _mongoc_crypt_destroy (_mongoc_crypt_t *crypt) _mongoc_ssl_opts_cleanup (&crypt->azure_tls_opt, true /* free_internal */); _mongoc_ssl_opts_cleanup (&crypt->gcp_tls_opt, true /* free_internal */); bson_destroy (&crypt->kms_providers); + mcd_azure_access_token_destroy (&crypt->azure_token); + mcd_mapof_kmsid_to_tlsopts_destroy (crypt->kmsid_to_tlsopts); bson_free (crypt); } @@ -1217,6 +1577,7 @@ _mongoc_crypt_auto_encrypt (_mongoc_crypt_t *crypt, mongocrypt_binary_t *cmd_bin = NULL; bool ret = false; + BSON_ASSERT_PARAM (collinfo_client); bson_init (cmd_out); state_machine = _state_machine_new (crypt); @@ -1290,26 +1651,31 @@ _mongoc_crypt_auto_decrypt (_mongoc_crypt_t *crypt, return ret; } -bool -_mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt, +// _create_explicit_state_machine_t creates a _state_machine_t for explicit +// encryption. The returned state machine may be used encrypting a value or +// encrypting an expression. +static _state_machine_t * +_create_explicit_state_machine (_mongoc_crypt_t *crypt, mongoc_collection_t *keyvault_coll, const char *algorithm, const bson_value_t *keyid, - char *keyaltname, + const char *keyaltname, const char *query_type, const int64_t *contention_factor, - const bson_value_t *value_in, - bson_value_t *value_out, + const bson_t *range_opts, bson_error_t *error) { - _state_machine_t *state_machine = NULL; - bson_t *to_encrypt_doc = NULL; - mongocrypt_binary_t *to_encrypt_bin = NULL; - bson_iter_t iter; - bool ret = false; - bson_t result = BSON_INITIALIZER; + BSON_ASSERT_PARAM (crypt); + BSON_ASSERT_PARAM (keyvault_coll); + BSON_ASSERT (algorithm || true); + BSON_ASSERT (keyid || true); + BSON_ASSERT (keyaltname || true); + BSON_ASSERT (query_type || true); + BSON_ASSERT (range_opts || true); + BSON_ASSERT (error || true); - value_out->value_type = BSON_TYPE_EOD; + _state_machine_t *state_machine = NULL; + bool ok = false; /* Create the context for the operation. */ state_machine = _state_machine_new (crypt); @@ -1325,6 +1691,19 @@ _mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt, goto fail; } + if (range_opts != NULL) { + /* mongocrypt error checks and parses range options */ + mongocrypt_binary_t *binary_range_opts = mongocrypt_binary_new_from_data ( + (uint8_t *) bson_get_data (range_opts), range_opts->len); + if (!mongocrypt_ctx_setopt_algorithm_range (state_machine->ctx, + binary_range_opts)) { + mongocrypt_binary_destroy (binary_range_opts); + _ctx_check_error (state_machine->ctx, error, true); + goto fail; + } + mongocrypt_binary_destroy (binary_range_opts); + } + if (query_type != NULL) { if (!mongocrypt_ctx_setopt_query_type ( state_machine->ctx, query_type, -1)) { @@ -1380,6 +1759,61 @@ _mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt, } } + ok = true; +fail: + if (!ok) { + _state_machine_destroy (state_machine); + state_machine = NULL; + } + return state_machine; +} + +bool +_mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt, + mongoc_collection_t *keyvault_coll, + const char *algorithm, + const bson_value_t *keyid, + const char *keyaltname, + const char *query_type, + const int64_t *contention_factor, + const bson_t *range_opts, + const bson_value_t *value_in, + bson_value_t *value_out, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (crypt); + BSON_ASSERT_PARAM (keyvault_coll); + BSON_ASSERT (algorithm || true); + BSON_ASSERT (keyid || true); + BSON_ASSERT (keyaltname || true); + BSON_ASSERT (query_type || true); + BSON_ASSERT (range_opts || true); + BSON_ASSERT_PARAM (value_in); + BSON_ASSERT_PARAM (value_out); + BSON_ASSERT (error || true); + + _state_machine_t *state_machine = NULL; + bson_t *to_encrypt_doc = NULL; + mongocrypt_binary_t *to_encrypt_bin = NULL; + bson_iter_t iter; + bool ret = false; + bson_t result = BSON_INITIALIZER; + + value_out->value_type = BSON_TYPE_EOD; + + state_machine = _create_explicit_state_machine (crypt, + keyvault_coll, + algorithm, + keyid, + keyaltname, + query_type, + contention_factor, + range_opts, + error); + if (!state_machine) { + goto fail; + } + to_encrypt_doc = bson_new (); BSON_APPEND_VALUE (to_encrypt_doc, "v", value_in); to_encrypt_bin = mongocrypt_binary_new_from_data ( @@ -1400,7 +1834,7 @@ _mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt, bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "encrypted result unexpected"); + "encrypted result unexpected: no 'v' found"); goto fail; } else { const bson_value_t *tmp; @@ -1418,6 +1852,103 @@ _mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt, return ret; } +bool +_mongoc_crypt_explicit_encrypt_expression (_mongoc_crypt_t *crypt, + mongoc_collection_t *keyvault_coll, + const char *algorithm, + const bson_value_t *keyid, + const char *keyaltname, + const char *query_type, + const int64_t *contention_factor, + const bson_t *range_opts, + const bson_t *expr_in, + bson_t *expr_out, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (crypt); + BSON_ASSERT_PARAM (keyvault_coll); + BSON_ASSERT (algorithm || true); + BSON_ASSERT (keyid || true); + BSON_ASSERT (keyaltname || true); + BSON_ASSERT (query_type || true); + BSON_ASSERT (range_opts || true); + BSON_ASSERT_PARAM (expr_in); + BSON_ASSERT_PARAM (expr_out); + BSON_ASSERT (error || true); + + _state_machine_t *state_machine = NULL; + bson_t *to_encrypt_doc = NULL; + mongocrypt_binary_t *to_encrypt_bin = NULL; + bson_iter_t iter; + bool ret = false; + bson_t result = BSON_INITIALIZER; + + bson_init (expr_out); + + state_machine = _create_explicit_state_machine (crypt, + keyvault_coll, + algorithm, + keyid, + keyaltname, + query_type, + contention_factor, + range_opts, + error); + if (!state_machine) { + goto fail; + } + + to_encrypt_doc = bson_new (); + BSON_APPEND_DOCUMENT (to_encrypt_doc, "v", expr_in); + to_encrypt_bin = mongocrypt_binary_new_from_data ( + (uint8_t *) bson_get_data (to_encrypt_doc), to_encrypt_doc->len); + if (!mongocrypt_ctx_explicit_encrypt_expression_init (state_machine->ctx, + to_encrypt_bin)) { + _ctx_check_error (state_machine->ctx, error, true); + goto fail; + } + + bson_destroy (&result); + if (!_state_machine_run (state_machine, &result, error)) { + goto fail; + } + + /* extract document */ + if (!bson_iter_init_find (&iter, &result, "v")) { + bson_set_error (error, + MONGOC_ERROR_CLIENT, + MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, + "encrypted result unexpected: no 'v' found"); + goto fail; + } else { + bson_t tmp; + + if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { + bson_set_error ( + error, + MONGOC_ERROR_CLIENT, + MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, + "encrypted result unexpected: 'v' is not a document, got: %s", + _mongoc_bson_type_to_str (bson_iter_type (&iter))); + goto fail; + } + + if (!_mongoc_iter_document_as_bson (&iter, &tmp, error)) { + goto fail; + } + + bson_copy_to (&tmp, expr_out); + } + + ret = true; +fail: + _state_machine_destroy (state_machine); + mongocrypt_binary_destroy (to_encrypt_bin); + bson_destroy (to_encrypt_doc); + bson_destroy (&result); + return ret; +} + bool _mongoc_crypt_explicit_decrypt (_mongoc_crypt_t *crypt, mongoc_collection_t *keyvault_coll, @@ -1517,9 +2048,7 @@ _mongoc_crypt_create_datakey (_mongoc_crypt_t *crypt, } if (keyaltnames) { - int i; - - for (i = 0; i < keyaltnames_count; i++) { + for (uint32_t i = 0u; i < keyaltnames_count; i++) { bool keyaltname_ret; mongocrypt_binary_t *keyaltname_bin; bson_t *keyaltname_doc; @@ -1584,6 +2113,9 @@ _mongoc_crypt_rewrap_many_datakey (_mongoc_crypt_t *crypt, mongocrypt_binary_t *filter_bin = NULL; bool ret = false; + // Caller must ensure `provider` is provided alongside `master_key`. + BSON_ASSERT (!master_key || provider); + bson_init (doc_out); state_machine = _state_machine_new (crypt); state_machine->keyvault_coll = keyvault_coll; diff --git a/src/mongoc/mongoc-cursor-array.c b/src/mongoc/mongoc-cursor-array.c index ee4143cb..ee7b2b5c 100644 --- a/src/mongoc/mongoc-cursor-array.c +++ b/src/mongoc/mongoc-cursor-array.c @@ -92,6 +92,8 @@ _mongoc_cursor_array_new (mongoc_client_t *client, const bson_t *opts, const char *field_name) { + BSON_ASSERT_PARAM (client); + mongoc_cursor_t *cursor = _mongoc_cursor_new_with_opts ( client, db_and_coll, opts, NULL, NULL, NULL); data_array_t *data = BSON_ALIGNED_ALLOC0 (data_array_t); diff --git a/src/mongoc/mongoc-cursor-change-stream.c b/src/mongoc/mongoc-cursor-change-stream.c index 8770ef24..451b42ba 100644 --- a/src/mongoc/mongoc-cursor-change-stream.c +++ b/src/mongoc/mongoc-cursor-change-stream.c @@ -120,7 +120,7 @@ _mongoc_cursor_change_stream_new (mongoc_client_t *client, mongoc_cursor_t *cursor; _data_change_stream_t *data; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (reply); data = BSON_ALIGNED_ALLOC0 (_data_change_stream_t); diff --git a/src/mongoc/mongoc-cursor-cmd-deprecated.c b/src/mongoc/mongoc-cursor-cmd-deprecated.c index b302801b..1edf5266 100644 --- a/src/mongoc/mongoc-cursor-cmd-deprecated.c +++ b/src/mongoc/mongoc-cursor-cmd-deprecated.c @@ -87,6 +87,8 @@ _mongoc_cursor_cmd_deprecated_new (mongoc_client_t *client, const bson_t *cmd, const mongoc_read_prefs_t *read_prefs) { + BSON_ASSERT_PARAM (client); + mongoc_cursor_t *cursor = _mongoc_cursor_new_with_opts (client, db_and_coll, diff --git a/src/mongoc/mongoc-cursor-cmd.c b/src/mongoc/mongoc-cursor-cmd.c index 34e89e5d..a333ed7f 100644 --- a/src/mongoc/mongoc-cursor-cmd.c +++ b/src/mongoc/mongoc-cursor-cmd.c @@ -49,13 +49,9 @@ _getmore_type (mongoc_cursor_t *cursor) wire_version = server_stream->sd->max_wire_version; mongoc_server_stream_cleanup (server_stream); - if ( - /* Server version 5.1 and newer do not support OP_GETMORE. */ - wire_version > WIRE_VERSION_5_0 || - /* Fallback to legacy OP_GETMORE wire protocol messages if exhaust cursor - requested with server version 3.6 or newer . */ - (wire_version >= WIRE_VERSION_FIND_CMD && - !_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST))) { + // CDRIVER-4722: always GETMORE_CMD once WIRE_VERSION_MIN >= + // WIRE_VERSION_4_2. + if (_mongoc_cursor_use_op_msg (cursor, wire_version)) { data->getmore_type = GETMORE_CMD; } else { data->getmore_type = OP_GETMORE; @@ -170,6 +166,8 @@ _mongoc_cursor_cmd_new (mongoc_client_t *client, const mongoc_read_prefs_t *default_prefs, const mongoc_read_concern_t *read_concern) { + BSON_ASSERT_PARAM (client); + mongoc_cursor_t *cursor; data_cmd_t *data = BSON_ALIGNED_ALLOC0 (data_cmd_t); @@ -194,6 +192,8 @@ _mongoc_cursor_cmd_new_from_reply (mongoc_client_t *client, const bson_t *opts, bson_t *reply) { + BSON_ASSERT_PARAM (client); + mongoc_cursor_t *cursor = _mongoc_cursor_cmd_new (client, NULL, cmd, opts, NULL, NULL, NULL); data_cmd_t *data = (data_cmd_t *) cursor->impl.data; @@ -213,5 +213,26 @@ _mongoc_cursor_cmd_new_from_reply (mongoc_client_t *client, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Couldn't parse cursor document"); } + + if (0 != cursor->cursor_id && 0 == cursor->server_id) { + // A non-zero cursor_id means the cursor is still open on the server. + // Expect the "serverId" option to have been passed. The "serverId" option + // identifies the server with the cursor. + // The server with the cursor is required to send a "getMore" or + // "killCursors" command. + bson_set_error ( + &cursor->error, + MONGOC_ERROR_CURSOR, + MONGOC_ERROR_CURSOR_INVALID_CURSOR, + "Expected `serverId` option to identify server with open cursor " + "(cursor ID is %" PRId64 "). " + "Consider using `mongoc_client_select_server` and using the " + "resulting server ID to create the cursor.", + cursor->cursor_id); + // Reset cursor_id to 0 to avoid an assertion error in + // `mongoc_cursor_destroy` when attempting to send "killCursors". + cursor->cursor_id = 0; + } + return cursor; } diff --git a/src/mongoc/mongoc-cursor-find.c b/src/mongoc/mongoc-cursor-find.c index 2c396256..e77d74b9 100644 --- a/src/mongoc/mongoc-cursor-find.c +++ b/src/mongoc/mongoc-cursor-find.c @@ -45,13 +45,8 @@ _prime (mongoc_cursor_t *cursor) mongoc_server_stream_cleanup (server_stream); /* set all mongoc_impl_t function pointers. */ - if ( - /* Server version 5.1 and newer do not support OP_QUERY. */ - wire_version > WIRE_VERSION_5_0 || - /* Fallback to legacy OP_QUERY wire protocol messages if exhaust cursor - requested with server version 3.6 or newer. */ - (wire_version >= WIRE_VERSION_FIND_CMD && - !_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST))) { + /* CDRIVER-4722: always find_cmd when server >= 4.2 */ + if (_mongoc_cursor_use_op_msg (cursor, wire_version)) { _mongoc_cursor_impl_find_cmd_init (cursor, &data->filter /* stolen */); } else { _mongoc_cursor_impl_find_opquery_init (cursor, @@ -92,6 +87,8 @@ _mongoc_cursor_find_new (mongoc_client_t *client, const mongoc_read_prefs_t *default_prefs, const mongoc_read_concern_t *read_concern) { + BSON_ASSERT_PARAM (client); + mongoc_cursor_t *cursor; data_find_t *data = BSON_ALIGNED_ALLOC0 (data_find_t); cursor = _mongoc_cursor_new_with_opts ( diff --git a/src/mongoc/mongoc-cursor-legacy.c b/src/mongoc/mongoc-cursor-legacy.c index 5f346d90..8c93d955 100644 --- a/src/mongoc/mongoc-cursor-legacy.c +++ b/src/mongoc/mongoc-cursor-legacy.c @@ -33,6 +33,7 @@ #include "mongoc-read-prefs-private.h" #include "mongoc-rpc-private.h" +#include static bool _mongoc_cursor_monitor_legacy_get_more (mongoc_cursor_t *cursor, @@ -100,8 +101,9 @@ _mongoc_cursor_monitor_legacy_query (mongoc_cursor_t *cursor, /* simulate a MongoDB 3.2+ "find" command */ _mongoc_cursor_prepare_find_command (cursor, filter, &doc); - bson_copy_to_excluding_noinit ( - &cursor->opts, &doc, "serverId", "maxAwaitTimeMS", "sessionId", NULL); + bsonBuildAppend ( + cursor->opts, + insert (doc, not(key ("serverId", "maxAwaitTimeMS", "sessionId")))); r = _mongoc_cursor_monitor_command (cursor, server_stream, &doc, "find"); @@ -112,97 +114,127 @@ _mongoc_cursor_monitor_legacy_query (mongoc_cursor_t *cursor, } +static bool +_mongoc_cursor_op_getmore_send (mongoc_cursor_t *cursor, + mongoc_server_stream_t *server_stream, + int32_t request_id, + int32_t flags, + mcd_rpc_message *rpc) +{ + BSON_ASSERT_PARAM (cursor); + BSON_ASSERT_PARAM (server_stream); + BSON_ASSERT_PARAM (rpc); + + const int32_t n_return = (flags & MONGOC_OP_QUERY_FLAG_TAILABLE_CURSOR) != 0 + ? 0 + : _mongoc_n_return (cursor); + + { + int32_t message_length = 0; + + message_length += mcd_rpc_header_set_message_length (rpc, 0); + message_length += mcd_rpc_header_set_request_id (rpc, request_id); + message_length += mcd_rpc_header_set_response_to (rpc, 0); + message_length += + mcd_rpc_header_set_op_code (rpc, MONGOC_OP_CODE_GET_MORE); + + message_length += sizeof (int32_t); // ZERO + message_length += + mcd_rpc_op_get_more_set_full_collection_name (rpc, cursor->ns); + message_length += + mcd_rpc_op_get_more_set_number_to_return (rpc, n_return); + message_length += + mcd_rpc_op_get_more_set_cursor_id (rpc, cursor->cursor_id); + + mcd_rpc_message_set_length (rpc, message_length); + } + + if (!_mongoc_cursor_monitor_legacy_get_more (cursor, server_stream)) { + return false; + } + + if (!mongoc_cluster_legacy_rpc_sendv_to_server ( + &cursor->client->cluster, rpc, server_stream, &cursor->error)) { + return false; + } + + return true; +} + void _mongoc_cursor_op_getmore (mongoc_cursor_t *cursor, mongoc_cursor_response_legacy_t *response) { - int64_t started; - mongoc_rpc_t rpc; - uint32_t request_id; - mongoc_cluster_t *cluster; - mongoc_query_flags_t flags; - mongoc_server_stream_t *server_stream; + BSON_ASSERT_PARAM (cursor); + BSON_ASSERT_PARAM (response); ENTRY; - started = bson_get_monotonic_time (); - cluster = &cursor->client->cluster; + const int64_t started = bson_get_monotonic_time (); + + mongoc_server_stream_t *const server_stream = + _mongoc_cursor_fetch_stream (cursor); - server_stream = _mongoc_cursor_fetch_stream (cursor); if (!server_stream) { - return; + GOTO (done); } + int32_t flags; if (!_mongoc_cursor_opts_to_flags (cursor, server_stream, &flags)) { GOTO (fail); } + mongoc_cluster_t *const cluster = &cursor->client->cluster; - if (cursor->in_exhaust) { - request_id = (uint32_t) response->rpc.header.request_id; - } else { - request_id = ++cluster->request_id; - - rpc.get_more.cursor_id = cursor->cursor_id; - rpc.header.msg_len = 0; - rpc.header.request_id = request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_GET_MORE; - rpc.get_more.zero = 0; - rpc.get_more.collection = cursor->ns; + const int32_t request_id = cursor->in_exhaust + ? mcd_rpc_header_get_request_id (response->rpc) + : ++cluster->request_id; - if (flags & MONGOC_QUERY_TAILABLE_CURSOR) { - rpc.get_more.n_return = 0; - } else { - rpc.get_more.n_return = _mongoc_n_return (cursor); - } - - if (!_mongoc_cursor_monitor_legacy_get_more (cursor, server_stream)) { - GOTO (fail); - } - - if (!mongoc_cluster_legacy_rpc_sendv_to_server ( - cluster, &rpc, server_stream, &cursor->error)) { - GOTO (fail); - } + if (!cursor->in_exhaust && + !_mongoc_cursor_op_getmore_send ( + cursor, server_stream, request_id, flags, response->rpc)) { + GOTO (fail); } + mcd_rpc_message_reset (response->rpc); _mongoc_buffer_clear (&response->buffer, false); - - /* reset the last known cursor id. */ cursor->cursor_id = 0; if (!_mongoc_client_recv (cursor->client, - &response->rpc, + response->rpc, &response->buffer, server_stream, &cursor->error)) { GOTO (fail); } - if (response->rpc.header.opcode != MONGOC_OPCODE_REPLY) { + const int32_t op_code = mcd_rpc_header_get_op_code (response->rpc); + if (op_code != MONGOC_OP_CODE_REPLY) { bson_set_error (&cursor->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid opcode. Expected %d, got %d.", - MONGOC_OPCODE_REPLY, - response->rpc.header.opcode); + "invalid opcode for OP_GET_MORE: expected %" PRId32 + ", got %" PRId32, + MONGOC_OP_CODE_REPLY, + op_code); GOTO (fail); } - if (response->rpc.header.response_to != request_id) { + const int32_t response_to = mcd_rpc_header_get_response_to (response->rpc); + if (response_to != request_id) { bson_set_error (&cursor->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid response_to for getmore. Expected %d, got %d.", + "invalid response_to for OP_GET_MORE: expected %" PRId32 + ", got %" PRId32, request_id, - response->rpc.header.response_to); + response_to); GOTO (fail); } - if (!_mongoc_rpc_check_ok (&response->rpc, - cursor->client->error_api_version, - &cursor->error, - &cursor->error_doc)) { + if (!mcd_rpc_message_check_ok (response->rpc, + cursor->client->error_api_version, + &cursor->error, + &cursor->error_doc)) { GOTO (fail); } @@ -210,11 +242,16 @@ _mongoc_cursor_op_getmore (mongoc_cursor_t *cursor, bson_reader_destroy (response->reader); } - cursor->cursor_id = response->rpc.reply.cursor_id; + cursor->cursor_id = mcd_rpc_op_reply_get_cursor_id (response->rpc); + + const void *documents = mcd_rpc_op_reply_get_documents (response->rpc); + if (documents == NULL) { + // Use a non-NULL pointer to satisfy precondition of + // `bson_reader_new_from_data`: + documents = ""; + } - response->reader = - bson_reader_new_from_data (response->rpc.reply.documents, - (size_t) response->rpc.reply.documents_len); + response->reader = bson_reader_new_from_data (documents, mcd_rpc_op_reply_get_documents_len (response->rpc)); _mongoc_cursor_monitor_succeeded (cursor, response, @@ -224,9 +261,11 @@ _mongoc_cursor_op_getmore (mongoc_cursor_t *cursor, "getMore"); GOTO (done); + fail: _mongoc_cursor_monitor_failed ( cursor, bson_get_monotonic_time () - started, server_stream, "getMore"); + done: mongoc_server_stream_cleanup (server_stream); } @@ -311,7 +350,7 @@ _mongoc_cursor_parse_opts_for_op_query (mongoc_cursor_t *cursor, bson_t *filter, bson_t *query /* OUT */, bson_t *fields /* OUT */, - mongoc_query_flags_t *flags /* OUT */, + int32_t *flags /* OUT */, int32_t *skip /* OUT */) { bool pushed_dollar_query; @@ -322,7 +361,7 @@ _mongoc_cursor_parse_opts_for_op_query (mongoc_cursor_t *cursor, const char *key; char *dollar_modifier; - *flags = MONGOC_QUERY_NONE; + *flags = MONGOC_OP_QUERY_FLAG_NONE; *skip = 0; /* assume we'll send filter straight to server, like "{a: 1}". if we find an @@ -356,9 +395,9 @@ _mongoc_cursor_parse_opts_for_op_query (mongoc_cursor_t *cursor, } /* the rest of the options, alphabetically */ else if (!strcmp (key, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS)) { - OPT_FLAG (MONGOC_QUERY_PARTIAL); + OPT_FLAG (MONGOC_OP_QUERY_FLAG_PARTIAL); } else if (!strcmp (key, MONGOC_CURSOR_AWAIT_DATA)) { - OPT_FLAG (MONGOC_QUERY_AWAIT_DATA); + OPT_FLAG (MONGOC_OP_QUERY_FLAG_AWAIT_DATA); } else if (!strcmp (key, MONGOC_CURSOR_COMMENT)) { OPT_CHECK (UTF8); PUSH_DOLLAR_QUERY (); @@ -453,121 +492,144 @@ _mongoc_cursor_parse_opts_for_op_query (mongoc_cursor_t *cursor, #undef OPT_SUBDOCUMENT -bool -_mongoc_cursor_op_query_find (mongoc_cursor_t *cursor, - bson_t *filter, - mongoc_cursor_response_legacy_t *response) +static bool +_mongoc_cursor_op_query_find_send (mongoc_cursor_t *cursor, + mongoc_server_stream_t *server_stream, + int32_t request_id, + bson_t *filter, + mcd_rpc_message *rpc) { - int64_t started; - uint32_t request_id; - mongoc_rpc_t rpc; - const bson_t *query_ptr; + bool ret = false; + + cursor->operation_id = ++cursor->client->cluster.operation_id; + + mongoc_assemble_query_result_t result = ASSEMBLE_QUERY_RESULT_INIT; bson_t query = BSON_INITIALIZER; bson_t fields = BSON_INITIALIZER; - mongoc_query_flags_t flags; - mongoc_assemble_query_result_t result = ASSEMBLE_QUERY_RESULT_INIT; - bool succeeded = false; - mongoc_server_stream_t *server_stream; + int32_t skip; + int32_t flags; + const bson_t *const query_ptr = _mongoc_cursor_parse_opts_for_op_query ( + cursor, server_stream, filter, &query, &fields, &flags, &skip); - ENTRY; + if (!query_ptr) { + GOTO (done); + } - server_stream = _mongoc_cursor_fetch_stream (cursor); - if (!server_stream) { - return false; + assemble_query ( + cursor->read_prefs, server_stream, query_ptr, flags, &result); + + { + int32_t message_length = 0; + + message_length += mcd_rpc_header_set_message_length (rpc, 0); + message_length += mcd_rpc_header_set_request_id (rpc, request_id); + message_length += mcd_rpc_header_set_response_to (rpc, 0); + message_length += mcd_rpc_header_set_op_code (rpc, MONGOC_OP_CODE_QUERY); + + message_length += mcd_rpc_op_query_set_flags (rpc, result.flags); + message_length += + mcd_rpc_op_query_set_full_collection_name (rpc, cursor->ns); + message_length += mcd_rpc_op_query_set_number_to_skip (rpc, skip); + message_length += + mcd_rpc_op_query_set_number_to_return (rpc, _mongoc_n_return (cursor)); + message_length += mcd_rpc_op_query_set_query ( + rpc, bson_get_data (result.assembled_query)); + + if (!bson_empty (&fields)) { + message_length += mcd_rpc_op_query_set_return_fields_selector ( + rpc, bson_get_data (&fields)); + } + + mcd_rpc_message_set_length (rpc, message_length); } - started = bson_get_monotonic_time (); + if (!_mongoc_cursor_monitor_legacy_query (cursor, filter, server_stream)) { + GOTO (done); + } - /* When the user explicitly provides a readConcern -- but the server - * doesn't support readConcern, we must error: - * https://github.com/mongodb/specifications/blob/master/source/read-write-concern/read-write-concern.rst#errors-1 - */ - if (cursor->read_concern->level != NULL && - server_stream->sd->max_wire_version < WIRE_VERSION_READ_CONCERN) { - bson_set_error (&cursor->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support readConcern"); + if (!mongoc_cluster_legacy_rpc_sendv_to_server ( + &cursor->client->cluster, rpc, server_stream, &cursor->error)) { GOTO (done); } - cursor->operation_id = ++cursor->client->cluster.operation_id; + ret = true; + +done: + assemble_query_result_cleanup (&result); + bson_destroy (&fields); + bson_destroy (&query); - request_id = ++cursor->client->cluster.request_id; + return ret; +} - rpc.header.msg_len = 0; - rpc.header.request_id = request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_QUERY; - rpc.query.flags = MONGOC_QUERY_NONE; - rpc.query.collection = cursor->ns; - rpc.query.skip = 0; - rpc.query.n_return = 0; - rpc.query.fields = NULL; +bool +_mongoc_cursor_op_query_find (mongoc_cursor_t *cursor, + bson_t *filter, + mongoc_cursor_response_legacy_t *response) +{ + BSON_ASSERT_PARAM (cursor); + BSON_ASSERT_PARAM (filter); + BSON_ASSERT_PARAM (response); - query_ptr = _mongoc_cursor_parse_opts_for_op_query ( - cursor, server_stream, filter, &query, &fields, &flags, &rpc.query.skip); + ENTRY; - if (!query_ptr) { - /* invalid opts. cursor->error is set */ - GOTO (done); - } + bool ret = false; - assemble_query ( - cursor->read_prefs, server_stream, query_ptr, flags, &result); + mongoc_server_stream_t *const server_stream = + _mongoc_cursor_fetch_stream (cursor); - rpc.query.query = bson_get_data (result.assembled_query); - rpc.query.flags = result.flags; - rpc.query.n_return = _mongoc_n_return (cursor); - if (!bson_empty (&fields)) { - rpc.query.fields = bson_get_data (&fields); + if (!server_stream) { + RETURN (false); } - /* cursor from mongoc_collection_find[_with_opts] is about to send its - * initial OP_QUERY to pre-3.2 MongoDB */ - if (!_mongoc_cursor_monitor_legacy_query (cursor, filter, server_stream)) { - GOTO (done); - } + const int64_t started = bson_get_monotonic_time (); + const int32_t request_id = ++cursor->client->cluster.request_id; + mcd_rpc_message *const rpc = mcd_rpc_message_new (); - if (!mongoc_cluster_legacy_rpc_sendv_to_server ( - &cursor->client->cluster, &rpc, server_stream, &cursor->error)) { + if (!_mongoc_cursor_op_query_find_send ( + cursor, server_stream, request_id, filter, rpc)) { GOTO (done); } + mcd_rpc_message_reset (rpc); _mongoc_buffer_clear (&response->buffer, false); if (!_mongoc_client_recv (cursor->client, - &response->rpc, + response->rpc, &response->buffer, server_stream, &cursor->error)) { GOTO (done); } - if (response->rpc.header.opcode != MONGOC_OPCODE_REPLY) { + const int32_t op_code = mcd_rpc_header_get_op_code (response->rpc); + if (op_code != MONGOC_OP_CODE_REPLY) { bson_set_error (&cursor->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid opcode. Expected %d, got %d.", - MONGOC_OPCODE_REPLY, - response->rpc.header.opcode); + "invalid opcode for OP_QUERY: expected %" PRId32 + ", got %" PRId32, + MONGOC_OP_CODE_REPLY, + op_code); GOTO (done); } - if (response->rpc.header.response_to != request_id) { + const int32_t response_to = mcd_rpc_header_get_response_to (response->rpc); + if (response_to != request_id) { bson_set_error (&cursor->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid response_to for query. Expected %d, got %d.", + "invalid response_to for OP_QUERY: expected %" PRId32 + ", got %" PRId32, request_id, - response->rpc.header.response_to); + response_to); GOTO (done); } - if (!_mongoc_rpc_check_ok (&response->rpc, - cursor->client->error_api_version, - &cursor->error, - &cursor->error_doc)) { + if (!mcd_rpc_message_check_ok (response->rpc, + cursor->client->error_api_version, + &cursor->error, + &cursor->error_doc)) { GOTO (done); } @@ -575,11 +637,16 @@ _mongoc_cursor_op_query_find (mongoc_cursor_t *cursor, bson_reader_destroy (response->reader); } - cursor->cursor_id = response->rpc.reply.cursor_id; + cursor->cursor_id = mcd_rpc_op_reply_get_cursor_id (response->rpc); + + const void *documents = mcd_rpc_op_reply_get_documents (response->rpc); + if (documents == NULL) { + // Use a non-NULL pointer to satisfy precondition of + // `bson_reader_new_from_data`: + documents = ""; + } - response->reader = - bson_reader_new_from_data (response->rpc.reply.documents, - (size_t) response->rpc.reply.documents_len); + response->reader = bson_reader_new_from_data (documents, mcd_rpc_op_reply_get_documents_len (response->rpc)); if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) { cursor->in_exhaust = true; @@ -592,25 +659,26 @@ _mongoc_cursor_op_query_find (mongoc_cursor_t *cursor, true, /* first_batch */ server_stream, "find"); - succeeded = true; + + ret = true; done: - if (!succeeded) { + if (!ret) { _mongoc_cursor_monitor_failed ( cursor, bson_get_monotonic_time () - started, server_stream, "find"); } + mcd_rpc_message_destroy (rpc); mongoc_server_stream_cleanup (server_stream); - assemble_query_result_cleanup (&result); - bson_destroy (&query); - bson_destroy (&fields); - return succeeded; + + return ret; } void _mongoc_cursor_response_legacy_init (mongoc_cursor_response_legacy_t *response) { + response->rpc = mcd_rpc_message_new (); _mongoc_buffer_init (&response->buffer, NULL, 0, NULL, NULL); } @@ -624,4 +692,5 @@ _mongoc_cursor_response_legacy_destroy ( response->reader = NULL; } _mongoc_buffer_destroy (&response->buffer); + mcd_rpc_message_destroy (response->rpc); } diff --git a/src/mongoc/mongoc-cursor-private.h b/src/mongoc/mongoc-cursor-private.h index b4196249..98cb8e4d 100644 --- a/src/mongoc/mongoc-cursor-private.h +++ b/src/mongoc/mongoc-cursor-private.h @@ -104,7 +104,7 @@ struct _mongoc_cursor_impl_t { /* pre-3.2 and exhaust cursor responses -- read documents from stream. */ typedef struct _mongoc_cursor_response_legacy { - mongoc_rpc_t rpc; + mcd_rpc_message *rpc; mongoc_buffer_t buffer; bson_reader_t *reader; } mongoc_cursor_response_legacy_t; @@ -217,7 +217,9 @@ _mongoc_cursor_get_more (mongoc_cursor_t *cursor); bool _mongoc_cursor_opts_to_flags (mongoc_cursor_t *cursor, mongoc_server_stream_t *stream, - mongoc_query_flags_t *flags /* OUT */); + int32_t *flags /* OUT */); +bool +_mongoc_cursor_use_op_msg (const mongoc_cursor_t *cursor, int32_t wire_version); void _mongoc_cursor_monitor_succeeded (mongoc_cursor_t *cursor, mongoc_cursor_response_legacy_t *response, diff --git a/src/mongoc/mongoc-cursor.c b/src/mongoc/mongoc-cursor.c index ffe56618..8e39e3bc 100644 --- a/src/mongoc/mongoc-cursor.c +++ b/src/mongoc/mongoc-cursor.c @@ -30,6 +30,8 @@ #include "mongoc-read-prefs-private.h" #include "mongoc-aggregate-private.h" +#include + #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "cursor" @@ -236,7 +238,6 @@ _mongoc_cursor_new_with_opts (mongoc_client_t *client, const mongoc_read_concern_t *read_concern) { mongoc_cursor_t *cursor; - mongoc_topology_description_type_t td_type; uint32_t server_id; mongoc_read_concern_t *read_concern_local = NULL; bson_error_t validate_err; @@ -245,7 +246,7 @@ _mongoc_cursor_new_with_opts (mongoc_client_t *client, ENTRY; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); cursor = BSON_ALIGNED_ALLOC0 (mongoc_cursor_t); cursor->client = client; @@ -311,19 +312,13 @@ _mongoc_cursor_new_with_opts (mongoc_client_t *client, (void) mongoc_cursor_set_hint (cursor, server_id); } - bson_copy_to_excluding_noinit (opts, - &cursor->opts, - "serverId", - "sessionId", - "bypassDocumentValidation", - NULL); - - - /* only include bypassDocumentValidation if it's true */ - if (bson_iter_init_find (&iter, opts, "bypassDocumentValidation") && - bson_iter_as_bool (&iter)) { - BSON_APPEND_BOOL (&cursor->opts, "bypassDocumentValidation", true); - } + // Selectively copy the options: + bsonBuildAppend ( + cursor->opts, + insert (*opts, + not(key ("serverId", "sessionId"), + // Drop bypassDocumentValidation if it isn't true: + allOf (key ("bypassDocumentValidation"), isFalse)))); } if (_mongoc_client_session_in_txn (cursor->client_session)) { @@ -369,16 +364,6 @@ _mongoc_cursor_new_with_opts (mongoc_client_t *client, "Cannot specify both 'exhaust' and 'limit'."); GOTO (finish); } - - td_type = _mongoc_topology_get_type (client->topology); - - if (td_type == MONGOC_TOPOLOGY_SHARDED) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot use exhaust cursor with sharded cluster."); - GOTO (finish); - } } (void) _mongoc_read_prefs_validate (cursor->read_prefs, &cursor->error); @@ -498,9 +483,9 @@ _mongoc_cursor_flags_to_opts (mongoc_query_flags_t qflags, /* Checks if the passed query was wrapped in a $query, and if so, parses the * query modifiers: - * https://docs.mongodb.com/manual/reference/operator/query-modifier/ + * https://www.mongodb.com/docs/manual/reference/operator/query-modifier/ * and translates them to find command options: - * https://docs.mongodb.com/manual/reference/command/find/ + * https://www.mongodb.com/docs/manual/reference/command/find/ * opts must be initialized, and may already have options set. * unwrapped must be uninitialized, and will be initialized at return. * Returns true if query was unwrapped. */ @@ -671,12 +656,19 @@ _mongoc_cursor_fetch_stream (mongoc_cursor_t *cursor) } } else { server_stream = - mongoc_cluster_stream_for_reads (&cursor->client->cluster, - cursor->read_prefs, - cursor->client_session, - &reply, - cursor->is_aggr_with_write_stage, - &cursor->error); + cursor->is_aggr_with_write_stage + ? mongoc_cluster_stream_for_aggr_with_write ( + &cursor->client->cluster, + cursor->read_prefs, + cursor->client_session, + &reply, + &cursor->error) + : mongoc_cluster_stream_for_reads (&cursor->client->cluster, + cursor->read_prefs, + cursor->client_session, + NULL, + &reply, + &cursor->error); if (server_stream) { /* Remember the selected server_id and whether primary read mode was @@ -773,8 +765,6 @@ _mongoc_cursor_monitor_succeeded (mongoc_cursor_t *cursor, bson_t docs_array; mongoc_apm_command_succeeded_t event; mongoc_client_t *client; - bson_t reply; - bson_t reply_cursor; ENTRY; @@ -790,16 +780,14 @@ _mongoc_cursor_monitor_succeeded (mongoc_cursor_t *cursor, bson_init (&docs_array); _mongoc_cursor_append_docs_array (cursor, &docs_array, response); - bson_init (&reply); - bson_append_int32 (&reply, "ok", 2, 1); - bson_append_document_begin (&reply, "cursor", 6, &reply_cursor); - bson_append_int64 (&reply_cursor, "id", 2, mongoc_cursor_get_id (cursor)); - bson_append_utf8 (&reply_cursor, "ns", 2, cursor->ns, cursor->nslen); - bson_append_array (&reply_cursor, - first_batch ? "firstBatch" : "nextBatch", - first_batch ? 10 : 9, - &docs_array); - bson_append_document_end (&reply, &reply_cursor); + bsonBuildDecl (reply, + kv ("ok", int32 (1)), + kv ("cursor", + doc (kv ("id", int64 (mongoc_cursor_get_id (cursor))), + kv ("ns", utf8_w_len (cursor->ns, cursor->nslen)), + kv (first_batch ? "firstBatch" : "nextBatch", + bsonArray (docs_array))))); + bson_destroy (&docs_array); mongoc_apm_command_succeeded_init (&event, @@ -832,7 +820,6 @@ _mongoc_cursor_monitor_failed (mongoc_cursor_t *cursor, { mongoc_apm_command_failed_t event; mongoc_client_t *client; - bson_t reply; ENTRY; @@ -845,8 +832,7 @@ _mongoc_cursor_monitor_failed (mongoc_cursor_t *cursor, /* we sent OP_QUERY/OP_GETMORE, fake a reply to find/getMore command: * {ok: 0} */ - bson_init (&reply); - bson_append_int32 (&reply, "ok", 2, 0); + bsonBuildDecl (reply, kv ("ok", int32 (0))); mongoc_apm_command_failed_init (&event, duration, @@ -889,12 +875,13 @@ _mongoc_cursor_monitor_failed (mongoc_cursor_t *cursor, bool _mongoc_cursor_opts_to_flags (mongoc_cursor_t *cursor, mongoc_server_stream_t *stream, - mongoc_query_flags_t *flags /* OUT */) + int32_t *flags /* OUT */) { + /* CDRIVER-4722: these flags are only used in legacy OP_QUERY */ bson_iter_t iter; const char *key; - *flags = MONGOC_QUERY_NONE; + *flags = MONGOC_OP_QUERY_FLAG_NONE; if (!bson_iter_init (&iter, &cursor->opts)) { bson_set_error (&cursor->error, @@ -908,32 +895,41 @@ _mongoc_cursor_opts_to_flags (mongoc_cursor_t *cursor, key = bson_iter_key (&iter); if (!strcmp (key, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS)) { - ADD_FLAG (flags, MONGOC_QUERY_PARTIAL); + ADD_FLAG (flags, MONGOC_OP_QUERY_FLAG_PARTIAL); } else if (!strcmp (key, MONGOC_CURSOR_AWAIT_DATA)) { - ADD_FLAG (flags, MONGOC_QUERY_AWAIT_DATA); + ADD_FLAG (flags, MONGOC_OP_QUERY_FLAG_AWAIT_DATA); } else if (!strcmp (key, MONGOC_CURSOR_EXHAUST)) { - ADD_FLAG (flags, MONGOC_QUERY_EXHAUST); + ADD_FLAG (flags, MONGOC_OP_QUERY_FLAG_EXHAUST); } else if (!strcmp (key, MONGOC_CURSOR_NO_CURSOR_TIMEOUT)) { - ADD_FLAG (flags, MONGOC_QUERY_NO_CURSOR_TIMEOUT); + ADD_FLAG (flags, MONGOC_OP_QUERY_FLAG_NO_CURSOR_TIMEOUT); } else if (!strcmp (key, MONGOC_CURSOR_OPLOG_REPLAY)) { - ADD_FLAG (flags, MONGOC_QUERY_OPLOG_REPLAY); + ADD_FLAG (flags, MONGOC_OP_QUERY_FLAG_OPLOG_REPLAY); } else if (!strcmp (key, MONGOC_CURSOR_TAILABLE)) { - ADD_FLAG (flags, MONGOC_QUERY_TAILABLE_CURSOR); + ADD_FLAG (flags, MONGOC_OP_QUERY_FLAG_TAILABLE_CURSOR); } } if (cursor->secondary_ok) { - *flags |= MONGOC_QUERY_SECONDARY_OK; + *flags |= MONGOC_OP_QUERY_FLAG_SECONDARY_OK; } else if (cursor->server_id && (stream->topology_type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY || stream->topology_type == MONGOC_TOPOLOGY_RS_NO_PRIMARY) && stream->sd->type != MONGOC_SERVER_RS_PRIMARY) { - *flags |= MONGOC_QUERY_SECONDARY_OK; + *flags |= MONGOC_OP_QUERY_FLAG_SECONDARY_OK; } return true; } +bool +_mongoc_cursor_use_op_msg (const mongoc_cursor_t *cursor, int32_t wire_version) +{ + /* CDRIVER-4722: always true once 4.2 is the minimum supported + No check needed for 3.6 as it's the current minimum */ + return !_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST) || + wire_version >= WIRE_VERSION_4_2; +} + bool _mongoc_cursor_run_command (mongoc_cursor_t *cursor, const bson_t *command, @@ -975,18 +971,10 @@ _mongoc_cursor_run_command (mongoc_cursor_t *cursor, "Invalid BSON in opts document"); GOTO (done); } - if (!mongoc_cmd_parts_append_opts (&parts, - &iter, - server_stream->sd->max_wire_version, - &cursor->error)) { + if (!mongoc_cmd_parts_append_opts (&parts, &iter, &cursor->error)) { _mongoc_bson_init_if_set (reply); GOTO (done); } - if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) { - MONGOC_WARNING ( - "exhaust cursors not supported with OP_MSG, using normal " - "cursor instead"); - } } if (parts.assembled.session) { @@ -1012,10 +1000,8 @@ _mongoc_cursor_run_command (mongoc_cursor_t *cursor, mongoc_session_opts_destroy (session_opts); } - if (!mongoc_cmd_parts_set_read_concern (&parts, - cursor->read_concern, - server_stream->sd->max_wire_version, - &cursor->error)) { + if (!mongoc_cmd_parts_set_read_concern ( + &parts, cursor->read_concern, &cursor->error)) { _mongoc_bson_init_if_set (reply); GOTO (done); } @@ -1023,18 +1009,33 @@ _mongoc_cursor_run_command (mongoc_cursor_t *cursor, db = bson_strndup (cursor->ns, cursor->dblen); parts.assembled.db_name = db; - if (!_mongoc_cursor_opts_to_flags ( - cursor, server_stream, &parts.user_query_flags)) { - _mongoc_bson_init_if_set (reply); - GOTO (done); + { + int32_t flags; + if (!_mongoc_cursor_opts_to_flags (cursor, server_stream, &flags)) { + _mongoc_bson_init_if_set (reply); + GOTO (done); + } + parts.user_query_flags = (mongoc_query_flags_t) flags; } - /* Exhaust cursors with OP_MSG not yet supported; fallback to normal cursor. - * user_query_flags is unused in OP_MSG, so this technically has no effect, - * but is done anyways to ensure the query flags match handling of options. - */ - if (parts.user_query_flags & MONGOC_QUERY_EXHAUST) { - parts.user_query_flags ^= MONGOC_QUERY_EXHAUST; + if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) { + const bool sharded = + _mongoc_topology_get_type (cursor->client->topology) == + MONGOC_TOPOLOGY_SHARDED; + const int32_t wire_version = server_stream->sd->max_wire_version; + if (sharded && wire_version < WIRE_VERSION_MONGOS_EXHAUST) { + /* Return error since mongos < 7.2 doesn't support exhaust cursors */ + bson_set_error (&cursor->error, + MONGOC_ERROR_CURSOR, + MONGOC_ERROR_CURSOR_INVALID_CURSOR, + "exhaust cursors require mongos with wire version: " + "%d, but mongos has wire version: %d.", + wire_version, + WIRE_VERSION_MONGOS_EXHAUST); + _mongoc_bson_init_if_set (reply); + GOTO (done); + } + parts.assembled.op_msg_is_exhaust = true; } /* we might use mongoc_cursor_set_hint to target a secondary but have no @@ -1047,9 +1048,8 @@ _mongoc_cursor_run_command (mongoc_cursor_t *cursor, is_primary = !cursor->read_prefs || cursor->read_prefs->mode == MONGOC_READ_PRIMARY; - if (strcmp (cmd_name, "getMore") != 0 && - server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG && - is_primary && parts.user_query_flags & MONGOC_QUERY_SECONDARY_OK) { + if (strcmp (cmd_name, "getMore") != 0 && is_primary && + parts.user_query_flags & MONGOC_QUERY_SECONDARY_OK) { parts.read_prefs = prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED); } else { @@ -1075,8 +1075,7 @@ _mongoc_cursor_run_command (mongoc_cursor_t *cursor, } if (cursor->write_concern && - !mongoc_write_concern_is_default (cursor->write_concern) && - server_stream->sd->max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN) { + !mongoc_write_concern_is_default (cursor->write_concern)) { parts.assembled.is_acknowledged = mongoc_write_concern_is_acknowledged (cursor->write_concern); mongoc_write_concern_append (cursor->write_concern, &parts.extra); @@ -1100,21 +1099,30 @@ _mongoc_cursor_run_command (mongoc_cursor_t *cursor, MONGOC_READ_ERR_RETRY) { is_retryable = false; - mongoc_server_stream_cleanup (server_stream); + { + mongoc_deprioritized_servers_t *const ds = + mongoc_deprioritized_servers_new (); - BSON_ASSERT (!cursor->is_aggr_with_write_stage && - "Cannot attempt a retry on an aggregate operation that " - "contains write stages"); - server_stream = - mongoc_cluster_stream_for_reads (&cursor->client->cluster, - cursor->read_prefs, - cursor->client_session, - reply, - /* Not aggregate-with-write */ false, - &cursor->error); - - if (server_stream && - server_stream->sd->max_wire_version >= WIRE_VERSION_RETRY_READS) { + mongoc_deprioritized_servers_add_if_sharded ( + ds, server_stream->topology_type, server_stream->sd); + + mongoc_server_stream_cleanup (server_stream); + + BSON_ASSERT (!cursor->is_aggr_with_write_stage && + "Cannot attempt a retry on an aggregate operation that " + "contains write stages"); + server_stream = + mongoc_cluster_stream_for_reads (&cursor->client->cluster, + cursor->read_prefs, + cursor->client_session, + ds, + reply, + &cursor->error); + + mongoc_deprioritized_servers_destroy (ds); + } + + if (server_stream) { cursor->server_id = server_stream->sd->id; parts.assembled.server_stream = server_stream; bson_destroy (reply); @@ -1375,12 +1383,10 @@ mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host) td = mc_tpld_take_ref (cursor->client->topology); description = mongoc_topology_description_server_by_id_const ( td.ptr, cursor->server_id, &cursor->error); - mc_tpld_drop_ref (&td); - if (!description) { - return; + if (description) { + *host = description->host; } - - *host = description->host; + mc_tpld_drop_ref (&td); EXIT; } @@ -1463,9 +1469,32 @@ void mongoc_cursor_set_batch_size (mongoc_cursor_t *cursor, uint32_t batch_size) { BSON_ASSERT (cursor); - - _mongoc_cursor_set_opt_int64 ( - cursor, MONGOC_CURSOR_BATCH_SIZE, (int64_t) batch_size); + bson_iter_t iter; + if (!bson_iter_init_find (&iter, &cursor->opts, MONGOC_CURSOR_BATCH_SIZE)) { + bson_append_int64 (&cursor->opts, + MONGOC_CURSOR_BATCH_SIZE, + MONGOC_CURSOR_BATCH_SIZE_LEN, + batch_size); + } else if (BSON_ITER_HOLDS_INT64 (&iter)) { + bson_iter_overwrite_int64 (&iter, (int64_t) batch_size); + } else if (BSON_ITER_HOLDS_INT32 (&iter)) { + if (!bson_in_range_int32_t_unsigned (batch_size)) { + MONGOC_WARNING ("unable to overwrite stored int32 batchSize with " + "out-of-range value %" PRIu32, + batch_size); + return; + } + bson_iter_overwrite_int32 (&iter, (int32_t) batch_size); + } else if (BSON_ITER_HOLDS_DOUBLE (&iter)) { + bson_iter_overwrite_double (&iter, (double) batch_size); + } else if (BSON_ITER_HOLDS_DECIMAL128 (&iter)) { + bson_decimal128_t val; + val.high = 0x3040000000000000; + val.low = (uint64_t) batch_size; + bson_iter_overwrite_decimal128 (&iter, &val); + } else { + MONGOC_WARNING ("unable to overwrite non-numeric stored batchSize"); + } } @@ -1598,17 +1627,15 @@ mongoc_cursor_new_from_command_reply (mongoc_client_t *client, bson_t cmd = BSON_INITIALIZER; bson_t opts = BSON_INITIALIZER; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (reply); /* options are passed through by adding them to reply. */ - bson_copy_to_excluding_noinit (reply, - &opts, - "cursor", - "ok", - "operationTime", - "$clusterTime", - "$gleStats", - NULL); + bsonBuildAppend ( + *reply, + insert ( + opts, + not(key ( + "cursor", "ok", "operationTime", "$clusterTime", "$gleStats")))); if (server_id) { bson_append_int64 (&opts, "serverId", 8, server_id); @@ -1630,7 +1657,7 @@ mongoc_cursor_new_from_command_reply_with_opts (mongoc_client_t *client, mongoc_cursor_t *cursor; bson_t cmd = BSON_INITIALIZER; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (reply); cursor = _mongoc_cursor_cmd_new_from_reply (client, &cmd, opts, reply); @@ -1718,9 +1745,11 @@ _mongoc_cursor_response_refresh (mongoc_cursor_t *cursor, /* server replies to find / aggregate with {cursor: {id: N, firstBatch: []}}, * to getMore command with {cursor: {id: N, nextBatch: []}}. */ if (_mongoc_cursor_run_command ( - cursor, command, opts, &response->reply, false) && - _mongoc_cursor_start_reading_response (cursor, response)) { - return; + cursor, command, opts, &response->reply, false)) { + if (_mongoc_cursor_start_reading_response (cursor, response)) { + cursor->in_exhaust = cursor->client->in_exhaust; + return; + } } if (!cursor->error.domain) { bson_set_error (&cursor->error, diff --git a/src/mongoc/mongoc-cyrus-private.h b/src/mongoc/mongoc-cyrus-private.h index 2fcb33a9..d4aeee56 100644 --- a/src/mongoc/mongoc-cyrus-private.h +++ b/src/mongoc/mongoc-cyrus-private.h @@ -46,6 +46,8 @@ struct _mongoc_cyrus_t { #define SASL_CALLBACK_FN(_f) ((int (*) (void)) (_f)) #endif +int +_mongoc_cyrus_verifyfile_cb (void *context, const char *file, sasl_verify_type_t type); void _mongoc_cyrus_init (mongoc_cyrus_t *sasl); bool diff --git a/src/mongoc/mongoc-cyrus.c b/src/mongoc/mongoc-cyrus.c index f3685bd1..830c2048 100644 --- a/src/mongoc/mongoc-cyrus.c +++ b/src/mongoc/mongoc-cyrus.c @@ -138,16 +138,59 @@ _mongoc_cyrus_get_user (mongoc_cyrus_t *sasl, return (sasl->credentials.user != NULL) ? SASL_OK : SASL_FAIL; } +static const char * +sasl_verify_type_to_str (sasl_verify_type_t type) +{ + switch (type) { + case SASL_VRFY_PLUGIN: + return "SASL_VRFY_PLUGIN"; + case SASL_VRFY_CONF: + return "SASL_VRFY_CONF"; + case SASL_VRFY_PASSWD: + return "SASL_VRFY_PASSWD"; + case SASL_VRFY_OTHER: + return "SASL_VRFY_OTHER"; + default: + return "Unknown"; + } +} + +int +_mongoc_cyrus_verifyfile_cb (void *context, const char *file, sasl_verify_type_t type) +{ + TRACE ("Attempting to load file: `%s`. Type is %s\n", file, sasl_verify_type_to_str (type)); + +#ifdef _WIN32 + // On Windows, Cyrus SASL hard-codes the plugin path. + // Only permit loading plugin from user configured path to prevent unintentional library loading. + if (type == SASL_VRFY_PLUGIN) { + const char *path_prefix = MONGOC_CYRUS_PLUGIN_PATH_PREFIX; + bool has_valid_prefix = (path_prefix && file == strstr (file, path_prefix)); + // Check if `file` has necessary prefix. + if (has_valid_prefix) { + return SASL_OK; + } + MONGOC_WARNING ("Refusing to load Cyrus SASL plugin at: '%s'. If needed, set CYRUS_PLUGIN_PATH_PREFIX (currently " + "'%s') to the absolute path prefix of the plugin during build configuration of the C Driver.", + file, + path_prefix ? path_prefix : "(unset)"); + return SASL_CONTINUE; + } +#endif + + return SASL_OK; +} + void _mongoc_cyrus_init (mongoc_cyrus_t *sasl) { - sasl_callback_t callbacks[] = { - {SASL_CB_AUTHNAME, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl}, - {SASL_CB_USER, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl}, - {SASL_CB_PASS, SASL_CALLBACK_FN (_mongoc_cyrus_get_pass), sasl}, - {SASL_CB_CANON_USER, SASL_CALLBACK_FN (_mongoc_cyrus_canon_user), sasl}, - {SASL_CB_LIST_END}}; + sasl_callback_t callbacks[] = {{SASL_CB_AUTHNAME, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl}, + {SASL_CB_USER, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl}, + {SASL_CB_PASS, SASL_CALLBACK_FN (_mongoc_cyrus_get_pass), sasl}, + {SASL_CB_CANON_USER, SASL_CALLBACK_FN (_mongoc_cyrus_canon_user), sasl}, + {SASL_CB_VERIFYFILE, SASL_CALLBACK_FN (_mongoc_cyrus_verifyfile_cb), NULL}, + {SASL_CB_LIST_END}}; BSON_ASSERT (sasl); @@ -303,8 +346,6 @@ _mongoc_cyrus_start (mongoc_cyrus_t *sasl, const char *raw = NULL; unsigned raw_len = 0; int status; - int b64_ret; - int outbuf_capacity; BSON_ASSERT (sasl); BSON_ASSERT (outbuf); @@ -349,19 +390,21 @@ _mongoc_cyrus_start (mongoc_cyrus_t *sasl, } *outbuflen = 0; - outbuf_capacity = mcommon_b64_ntop_calculate_target_size (raw_len); + const size_t outbuf_capacity = + mcommon_b64_ntop_calculate_target_size (raw_len); *outbuf = bson_malloc (outbuf_capacity); - b64_ret = mcommon_b64_ntop ( + const int b64_ret = mcommon_b64_ntop ( (uint8_t *) raw, raw_len, (char *) *outbuf, outbuf_capacity); - if (b64_ret == -1) { + if (b64_ret < 0) { bson_set_error (error, MONGOC_ERROR_SASL, MONGOC_ERROR_CLIENT_AUTHENTICATE, "Unable to base64 encode client SASL message"); return false; } else { - *outbuflen = b64_ret; + BSON_ASSERT (bson_in_range_signed (uint32_t, b64_ret)); + *outbuflen = (uint32_t) b64_ret; } return true; @@ -379,11 +422,6 @@ _mongoc_cyrus_step (mongoc_cyrus_t *sasl, const char *raw = NULL; unsigned rawlen = 0; int status; - char *decoded; /* post base64 decoded data */ - uint32_t decoded_len; - uint32_t decoded_capacity; - uint32_t outbuf_capacity; - int b64_ret; BSON_ASSERT (sasl); if (sasl->step > 1) { @@ -415,24 +453,28 @@ _mongoc_cyrus_step (mongoc_cyrus_t *sasl, return false; } - decoded_len = 0; - decoded_capacity = mcommon_b64_pton_calculate_target_size (inbuflen); - decoded = bson_malloc (decoded_capacity); - b64_ret = - mcommon_b64_pton ((char *) inbuf, (uint8_t *) decoded, decoded_capacity); - if (b64_ret == -1) { - bson_set_error (error, - MONGOC_ERROR_SASL, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "Unable to base64 decode client SASL message"); - bson_free (decoded); - bson_free (*outbuf); - *outbuf = NULL; - return false; - } else { - /* Set the output length to the number of bytes actually decoded to - * excluding the NULL. */ - decoded_len = b64_ret; + unsigned int decoded_len = 0; + const size_t decoded_capacity = + mcommon_b64_pton_calculate_target_size (inbuflen); + + char *const decoded = bson_malloc (decoded_capacity); + { + const int b64_ret = mcommon_b64_pton ( + (char *) inbuf, (uint8_t *) decoded, decoded_capacity); + if (b64_ret < 0) { + bson_set_error (error, + MONGOC_ERROR_SASL, + MONGOC_ERROR_CLIENT_AUTHENTICATE, + "Unable to base64 decode client SASL message"); + bson_free (decoded); + bson_free (*outbuf); + *outbuf = NULL; + return false; + } else { + /* Set the output length to the number of bytes actually decoded to + * excluding the NULL. */ + decoded_len = (unsigned int) b64_ret; + } } TRACE ("%s", "Running client_step"); @@ -446,23 +488,27 @@ _mongoc_cyrus_step (mongoc_cyrus_t *sasl, } *outbuflen = 0; - outbuf_capacity = mcommon_b64_ntop_calculate_target_size (rawlen); + const size_t outbuf_capacity = + mcommon_b64_ntop_calculate_target_size (rawlen); *outbuf = bson_malloc0 (outbuf_capacity); - b64_ret = mcommon_b64_ntop ( - (const uint8_t *) raw, rawlen, (char *) *outbuf, outbuf_capacity); - if (b64_ret == -1) { - bson_set_error (error, - MONGOC_ERROR_SASL, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "Unable to base64 encode client SASL message"); - bson_free (decoded); - bson_free (*outbuf); - *outbuf = NULL; - return false; - } else { - /* Set the output length to the number of characters written excluding the - * NULL. */ - *outbuflen = b64_ret; + { + const int b64_ret = mcommon_b64_ntop ( + (const uint8_t *) raw, rawlen, (char *) *outbuf, outbuf_capacity); + if (b64_ret < 0) { + bson_set_error (error, + MONGOC_ERROR_SASL, + MONGOC_ERROR_CLIENT_AUTHENTICATE, + "Unable to base64 encode client SASL message"); + bson_free (decoded); + bson_free (*outbuf); + *outbuf = NULL; + return false; + } else { + /* Set the output length to the number of characters written excluding + * the NULL. */ + BSON_ASSERT (bson_in_range_signed (uint32_t, b64_ret)); + *outbuflen = (uint32_t) b64_ret; + } } bson_free (decoded); diff --git a/src/mongoc/mongoc-database-private.h b/src/mongoc/mongoc-database-private.h index 4405b5f7..64026430 100644 --- a/src/mongoc/mongoc-database-private.h +++ b/src/mongoc/mongoc-database-private.h @@ -67,6 +67,39 @@ _mongoc_get_encryptedFields_from_server (mongoc_client_t *client, bson_t *encryptedFields, bson_error_t *error); +/** + * @brief Look up the encryptedFields to use for the given collection. + * + * If the collection options contains an encryptedFields, those are returned. + * If the client has an encryptedFieldsMap entry for the collection within the + * given database, those are returned. If neither, an empty document is + * returned. + * + * @param client The client with which to search an encryptedFieldsMap + * @param dbName The name of the database where the collection will/does live + * @param collName The name of the collection + * @param opts (Optional) The collection options, which may contain the + * fields + * @param checkEncryptedFieldsMap If false, the encryptedFieldsMap will not be + * checked. + * @param[out] encryptedFields An output where a view of the encryptedFields + * will be written + * @param[out] error An error output + * @retval true If there was no error + * @retval false Otherwise + * + * @note Upon returning `true`, check whether `*encryptedFields` is empty to + * determine whether fields have been found. + */ +bool +_mongoc_get_collection_encryptedFields (mongoc_client_t *client, + const char *dbName, + const char *collName, + const bson_t *opts, + bool checkEncryptedFieldsMap, + bson_t *encryptedFields, + bson_error_t *error); + /* _mongoc_get_encryptedField_state_collection returns the state collection * name. Returns NULL on error. */ char * diff --git a/src/mongoc/mongoc-database.c b/src/mongoc/mongoc-database.c index e26a5bde..46fc2d62 100644 --- a/src/mongoc/mongoc-database.c +++ b/src/mongoc/mongoc-database.c @@ -30,6 +30,8 @@ #include "mongoc-write-concern-private.h" #include "mongoc-change-stream-private.h" +#include + #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "database" @@ -464,7 +466,7 @@ mongoc_database_add_user (mongoc_database_t *database, bson_error_t *error) { bson_t cmd; - bson_t ar; + bson_array_builder_t *ar; bool ret = false; ENTRY; @@ -482,8 +484,8 @@ mongoc_database_add_user (mongoc_database_t *database, if (roles) { BSON_APPEND_ARRAY (&cmd, "roles", roles); } else { - bson_append_array_begin (&cmd, "roles", 5, &ar); - bson_append_array_end (&cmd, &ar); + bson_append_array_builder_begin (&cmd, "roles", 5, &ar); + bson_append_array_builder_end (&cmd, ar); } ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error); @@ -1013,15 +1015,13 @@ _mongoc_get_encryptedField_state_collection ( if (0 == strcmp (state_collection_suffix, "esc")) { fieldName = "escCollection"; - } else if (0 == strcmp (state_collection_suffix, "ecc")) { - fieldName = "eccCollection"; } else if (0 == strcmp (state_collection_suffix, "ecoc")) { fieldName = "ecocCollection"; } else { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, - "expected state_collection_suffix to be 'esc', 'ecc', or " + "expected state_collection_suffix to be 'esc' or " "'ecoc', got: %s", state_collection_suffix); return NULL; @@ -1095,11 +1095,37 @@ create_collection_with_encryptedFields (mongoc_database_t *database, mongoc_collection_t *dataCollection = NULL; bool ok = false; bson_t *cc_opts = NULL; + + // Check the wire version to ensure server is 7.0.0 or newer. + { + mongoc_server_stream_t *stream = + mongoc_cluster_stream_for_writes (&database->client->cluster, + NULL /* client session */, + NULL /* deprioritized servers */, + NULL /* reply */, + error); + if (!stream) { + goto fail; + } + if (stream->sd->max_wire_version < WIRE_VERSION_7_0) { + bson_set_error ( + error, + MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, + "Driver support of Queryable Encryption is incompatible " + "with server. Upgrade server to use Queryable Encryption. " + "Got maxWireVersion %" PRId32 " but need maxWireVersion >= %d", + stream->sd->max_wire_version, + WIRE_VERSION_7_0); + mongoc_server_stream_cleanup (stream); + goto fail; + } + mongoc_server_stream_cleanup (stream); + } + bool state_collections_ok = create_encField_state_collection ( database, encryptedFields, name, "esc", error) && - create_encField_state_collection ( - database, encryptedFields, name, "ecc", error) && create_encField_state_collection ( database, encryptedFields, name, "ecoc", error); if (!state_collections_ok) { @@ -1124,26 +1150,10 @@ create_collection_with_encryptedFields (mongoc_database_t *database, /* Create index on __safeContent__. */ { bson_t *keys = BCON_NEW ("__safeContent__", BCON_INT32 (1)); - char *index_name; - bson_t *create_indexes; - - index_name = mongoc_collection_keys_to_index_string (keys); - create_indexes = BCON_NEW ("createIndexes", - BCON_UTF8 (name), - "indexes", - "[", - "{", - "key", - BCON_DOCUMENT (keys), - "name", - BCON_UTF8 (index_name), - "}", - "]"); - - ok = mongoc_database_write_command_with_opts ( - database, create_indexes, NULL /* opts */, NULL /* reply */, error); - bson_destroy (create_indexes); - bson_free (index_name); + mongoc_index_model_t *im = mongoc_index_model_new (keys, NULL /* opts */); + ok = mongoc_collection_create_indexes_with_opts ( + dataCollection, &im, 1, NULL /* opts */, NULL /* reply */, error); + mongoc_index_model_destroy (im); bson_destroy (keys); if (!ok) { goto fail; @@ -1168,6 +1178,8 @@ _mongoc_get_encryptedFields_from_map (mongoc_client_t *client, bson_t *encryptedFields, bson_error_t *error) { + BSON_ASSERT_PARAM (client); + const bson_t *efMap = client->topology->encrypted_fields_map; bson_init (encryptedFields); @@ -1201,6 +1213,8 @@ _mongoc_get_encryptedFields_from_server (mongoc_client_t *client, bson_t *encryptedFields, bson_error_t *error) { + BSON_ASSERT_PARAM (client); + mongoc_database_t *db = mongoc_client_get_database (client, dbName); bson_t *opts = BCON_NEW ("filter", "{", "name", BCON_UTF8 (collName), "}"); mongoc_cursor_t *cursor; @@ -1246,39 +1260,94 @@ _mongoc_get_encryptedFields_from_server (mongoc_client_t *client, return ret; } +bool +_mongoc_get_collection_encryptedFields (mongoc_client_t *client, + const char *dbName, + const char *collName, + const bson_t *opts, + bool checkEncryptedFieldsMap, + bson_t *encryptedFields, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (client); + BSON_ASSERT_PARAM (dbName); + BSON_ASSERT_PARAM (collName); + BSON_ASSERT (opts || true); + BSON_ASSERT_PARAM (encryptedFields); + BSON_ASSERT (error || true); + + bson_init (encryptedFields); // Initially empty + + if (opts) { + // We have collection options, which may have encryptedFields in it + bool found = false; + bsonParse ( + *opts, + find (key ("encryptedFields"), + if (not(type (doc)), + then (error ("'encryptedFields' should be a document"))), + // Update encryptedFields to be a reference to the subdocument: + storeDocRef (*encryptedFields), + do (found = true))); + if (bsonParseError) { + // Error while parsing + bson_set_error (error, + MONGOC_ERROR_COMMAND, + MONGOC_ERROR_COMMAND_INVALID_ARG, + "Invalid createCollection command options: %s", + bsonParseError); + return false; + } else if (found) { + // Found it! + return true; + } else { + // Nothing found in the options + } + } + + // Look in the encryptedFieldsMap based on this collection name + if (checkEncryptedFieldsMap && + !_mongoc_get_encryptedFields_from_map ( + client, dbName, collName, encryptedFields, error)) { + // Error during lookup. + return false; + } + + // No error. We may or may not have found encryptedFields. The caller + // determines this by checking if encryptedFields is empty. + return true; +} + mongoc_collection_t * mongoc_database_create_collection (mongoc_database_t *database, const char *name, const bson_t *opts, bson_error_t *error) { - bson_iter_t iter; - bson_t encryptedFields = BSON_INITIALIZER; - - if (opts && bson_iter_init_find (&iter, opts, "encryptedFields")) { - if (!_mongoc_iter_document_as_bson (&iter, &encryptedFields, error)) { - return NULL; - } - } + BSON_ASSERT_PARAM (database); + BSON_ASSERT_PARAM (name); + BSON_ASSERT (opts || true); + BSON_ASSERT (error || true); - if (bson_empty (&encryptedFields)) { - if (!_mongoc_get_encryptedFields_from_map ( - database->client, - mongoc_database_get_name (database), - name, - &encryptedFields, - error)) { - return NULL; - } + bson_t encryptedFields = BSON_INITIALIZER; + if (!_mongoc_get_collection_encryptedFields ( + database->client, + mongoc_database_get_name (database), + name, + opts, + true /* checkEncryptedFieldsMap */, + &encryptedFields, + error)) { + // Error during fields lookup + bson_destroy (&encryptedFields); + return false; } if (!bson_empty (&encryptedFields)) { - bson_t opts_without_encryptedFields = BSON_INITIALIZER; - - if (opts) { - bson_copy_to_excluding_noinit ( - opts, &opts_without_encryptedFields, "encryptedFields", NULL); - } + // Clone 'opts' without the encryptedFields element + bsonBuildDecl ( + opts_without_encryptedFields, + if (opts, then (insert (*opts, not(key ("encryptedFields")))))); mongoc_collection_t *ret = create_collection_with_encryptedFields (database, @@ -1287,11 +1356,12 @@ mongoc_database_create_collection (mongoc_database_t *database, &encryptedFields, error); - bson_destroy (&opts_without_encryptedFields); bson_destroy (&encryptedFields); + bson_destroy (&opts_without_encryptedFields); return ret; } + bson_destroy (&encryptedFields); return create_collection (database, name, opts, error); } diff --git a/src/mongoc/mongoc-deprioritized-servers-private.h b/src/mongoc/mongoc-deprioritized-servers-private.h new file mode 100644 index 00000000..6e9b0333 --- /dev/null +++ b/src/mongoc/mongoc-deprioritized-servers-private.h @@ -0,0 +1,51 @@ +/* + * Copyright 2024 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mongoc-prelude.h" + +#ifndef MONGOC_DEPRIORITIZED_SERVERS_PRIVATE_H +#define MONGOC_DEPRIORITIZED_SERVERS_PRIVATE_H + +#include + +#include "mongoc-server-description.h" + +#include + +BSON_BEGIN_DECLS + +typedef struct _mongoc_deprioritized_servers_t mongoc_deprioritized_servers_t; + +mongoc_deprioritized_servers_t * +mongoc_deprioritized_servers_new (void); + +void +mongoc_deprioritized_servers_destroy ( + mongoc_deprioritized_servers_t *ds); + +void +mongoc_deprioritized_servers_add ( + mongoc_deprioritized_servers_t *ds, + const mongoc_server_description_t *sd); + +bool +mongoc_deprioritized_servers_contains ( + const mongoc_deprioritized_servers_t *ds, + const mongoc_server_description_t *sd); + +BSON_END_DECLS + +#endif // MONGOC_DEPRIORITIZED_SERVERS_PRIVATE_H diff --git a/src/mongoc/mongoc-deprioritized-servers.c b/src/mongoc/mongoc-deprioritized-servers.c new file mode 100644 index 00000000..71369f59 --- /dev/null +++ b/src/mongoc/mongoc-deprioritized-servers.c @@ -0,0 +1,58 @@ +#include "mongoc-deprioritized-servers-private.h" + +#include "mongoc-set-private.h" + +// Dedicated non-zero value to avoid confusing "key is present with a NULL item" +// from "key is not present" (also NULL). +#define MONGOC_DEPRIORITIZED_SERVERS_ITEM_VALUE ((void *) 1) + +struct _mongoc_deprioritized_servers_t { + // Use server ID (uint32_t) as keys to identify deprioritized servers. + mongoc_set_t *ids; +}; + +mongoc_deprioritized_servers_t * +mongoc_deprioritized_servers_new (void) +{ + mongoc_deprioritized_servers_t *const ret = bson_malloc (sizeof (*ret)); + + *ret = (mongoc_deprioritized_servers_t){ + .ids = mongoc_set_new (1u, NULL, NULL), + }; + + return ret; +} + +void +mongoc_deprioritized_servers_destroy (mongoc_deprioritized_servers_t *ds) +{ + if (!ds) { + return; + } + + mongoc_set_destroy (ds->ids); + bson_free (ds); +} + +void +mongoc_deprioritized_servers_add (mongoc_deprioritized_servers_t *ds, + const mongoc_server_description_t *sd) +{ + BSON_ASSERT_PARAM (ds); + BSON_ASSERT_PARAM (sd); + + mongoc_set_add (ds->ids, + mongoc_server_description_id (sd), + MONGOC_DEPRIORITIZED_SERVERS_ITEM_VALUE); +} + +bool +mongoc_deprioritized_servers_contains (const mongoc_deprioritized_servers_t *ds, + const mongoc_server_description_t *sd) +{ + BSON_ASSERT_PARAM (ds); + BSON_ASSERT_PARAM (sd); + + return mongoc_set_get_const (ds->ids, mongoc_server_description_id (sd)) == + MONGOC_DEPRIORITIZED_SERVERS_ITEM_VALUE; +} diff --git a/src/mongoc/mongoc-error-private.h b/src/mongoc/mongoc-error-private.h index 3e4211cc..073c76d8 100644 --- a/src/mongoc/mongoc-error-private.h +++ b/src/mongoc/mongoc-error-private.h @@ -19,6 +19,8 @@ #include #include +#include "mongoc-server-description.h" + BSON_BEGIN_DECLS typedef enum { @@ -38,6 +40,7 @@ typedef enum { MONGOC_SERVER_ERR_NETWORKTIMEOUT = 89, MONGOC_SERVER_ERR_SHUTDOWNINPROGRESS = 91, MONGOC_SERVER_ERR_FAILEDTOSATISFYREADPREFERENCE = 133, + MONGOC_SERVER_ERR_READCONCERNMAJORITYNOTAVAILABLEYET = 134, MONGOC_SERVER_ERR_STALEEPOCH = 150, MONGOC_SERVER_ERR_PRIMARYSTEPPEDDOWN = 189, MONGOC_SERVER_ERR_ELECTIONINPROGRESS = 216, @@ -64,11 +67,14 @@ _mongoc_error_copy_labels_and_upsert (const bson_t *src, bson_t *dst, char *label); +void +_mongoc_write_error_append_retryable_label (bson_t *reply); + void _mongoc_write_error_handle_labels (bool cmd_ret, const bson_error_t *cmd_err, bson_t *reply, - int32_t server_max_wire_version); + const mongoc_server_description_t *sd); bool _mongoc_error_is_shutdown (bson_error_t *error); @@ -85,4 +91,10 @@ _mongoc_error_is_state_change (bson_error_t *error); bool _mongoc_error_is_network (const bson_error_t *error); +bool +_mongoc_error_is_server (const bson_error_t *error); + +bool +_mongoc_error_is_auth (const bson_error_t *error); + BSON_END_DECLS diff --git a/src/mongoc/mongoc-error.c b/src/mongoc/mongoc-error.c index 1e8ce7dd..b25d910a 100644 --- a/src/mongoc/mongoc-error.c +++ b/src/mongoc/mongoc-error.c @@ -20,6 +20,7 @@ #include "mongoc-error-private.h" #include "mongoc-rpc-private.h" #include "mongoc-client-private.h" +#include "mongoc-server-description-private.h" bool mongoc_error_has_label (const bson_t *reply, const char *label) @@ -40,27 +41,11 @@ mongoc_error_has_label (const bson_t *reply, const char *label) } } - if (!bson_iter_init_find (&iter, reply, "writeConcernError")) { - return false; - } - - BSON_ASSERT (bson_iter_recurse (&iter, &iter)); - - if (bson_iter_find (&iter, "errorLabels") && - bson_iter_recurse (&iter, &error_labels)) { - while (bson_iter_next (&error_labels)) { - if (BSON_ITER_HOLDS_UTF8 (&error_labels) && - !strcmp (bson_iter_utf8 (&error_labels, NULL), label)) { - return true; - } - } - } - return false; } -static bool -_mongoc_error_is_server (bson_error_t *error) +bool +_mongoc_error_is_server (const bson_error_t *error) { if (!error) { return false; @@ -96,7 +81,7 @@ _mongoc_write_error_is_retryable (bson_error_t *error) } } -static void +void _mongoc_write_error_append_retryable_label (bson_t *reply) { bson_t reply_local = BSON_INITIALIZER; @@ -118,7 +103,7 @@ void _mongoc_write_error_handle_labels (bool cmd_ret, const bson_error_t *cmd_err, bson_t *reply, - int32_t server_max_wire_version) + const mongoc_server_description_t *sd) { bson_error_t error; @@ -131,14 +116,21 @@ _mongoc_write_error_handle_labels (bool cmd_ret, return; } - if (server_max_wire_version >= WIRE_VERSION_RETRYABLE_WRITE_ERROR_LABEL) { + if (sd->max_wire_version >= WIRE_VERSION_RETRYABLE_WRITE_ERROR_LABEL) { return; } - /* check for a server error. */ - if (_mongoc_cmd_check_ok_no_wce ( - reply, MONGOC_ERROR_API_VERSION_2, &error)) { - return; + /* Check for a server error. Do not consult writeConcernError for pre-4.4 + * mongos. */ + if (sd->type == MONGOC_SERVER_MONGOS) { + if (_mongoc_cmd_check_ok (reply, MONGOC_ERROR_API_VERSION_2, &error)) { + return; + } + } else { + if (_mongoc_cmd_check_ok_no_wce ( + reply, MONGOC_ERROR_API_VERSION_2, &error)) { + return; + } } if (_mongoc_write_error_is_retryable (&error)) { @@ -184,12 +176,14 @@ _mongoc_read_error_get_type (bool cmd_ret, } switch (error.code) { + case MONGOC_SERVER_ERR_EXCEEDEDTIMELIMIT: case MONGOC_SERVER_ERR_INTERRUPTEDATSHUTDOWN: case MONGOC_SERVER_ERR_INTERRUPTEDDUETOREPLSTATECHANGE: case MONGOC_SERVER_ERR_NOTPRIMARY: case MONGOC_SERVER_ERR_NOTPRIMARYNOSECONDARYOK: case MONGOC_SERVER_ERR_NOTPRIMARYORSECONDARY: case MONGOC_SERVER_ERR_PRIMARYSTEPPEDDOWN: + case MONGOC_SERVER_ERR_READCONCERNMAJORITYNOTAVAILABLEYET: case MONGOC_SERVER_ERR_SHUTDOWNINPROGRESS: case MONGOC_SERVER_ERR_HOSTNOTFOUND: case MONGOC_SERVER_ERR_HOSTUNREACHABLE: @@ -212,28 +206,23 @@ _mongoc_error_copy_labels_and_upsert (const bson_t *src, { bson_iter_t iter; bson_iter_t src_label; - bson_t dst_labels; - char str[16]; - uint32_t i = 0; - const char *key; + bson_array_builder_t *dst_labels; - BSON_APPEND_ARRAY_BEGIN (dst, "errorLabels", &dst_labels); - BSON_APPEND_UTF8 (&dst_labels, "0", label); + BSON_APPEND_ARRAY_BUILDER_BEGIN (dst, "errorLabels", &dst_labels); + bson_array_builder_append_utf8 (dst_labels, label, -1); /* append any other errorLabels already in "src" */ if (bson_iter_init_find (&iter, src, "errorLabels") && bson_iter_recurse (&iter, &src_label)) { while (bson_iter_next (&src_label) && BSON_ITER_HOLDS_UTF8 (&src_label)) { if (strcmp (bson_iter_utf8 (&src_label, NULL), label) != 0) { - i++; - bson_uint32_to_string (i, &key, str, sizeof str); - BSON_APPEND_UTF8 ( - &dst_labels, key, bson_iter_utf8 (&src_label, NULL)); + bson_array_builder_append_utf8 ( + dst_labels, bson_iter_utf8 (&src_label, NULL), -1); } } } - bson_append_array_end (dst, &dst_labels); + bson_append_array_builder_end (dst, dst_labels); } /* Defined in SDAM spec under "Application Errors". @@ -270,7 +259,8 @@ _mongoc_error_is_not_primary (bson_error_t *error) case MONGOC_SERVER_ERR_NOTPRIMARYNOSECONDARYOK: case MONGOC_SERVER_ERR_LEGACYNOTPRIMARY: return true; - /* All errors where no code was found are marked as MONGOC_ERROR_QUERY_FAILURE */ + /* All errors where no code was found are marked as + * MONGOC_ERROR_QUERY_FAILURE */ case MONGOC_ERROR_QUERY_FAILURE: return NULL != strstr (error->message, "not master"); default: @@ -291,7 +281,8 @@ _mongoc_error_is_recovering (bson_error_t *error) case MONGOC_SERVER_ERR_PRIMARYSTEPPEDDOWN: case MONGOC_SERVER_ERR_SHUTDOWNINPROGRESS: return true; - /* All errors where no code was found are marked as MONGOC_ERROR_QUERY_FAILURE */ + /* All errors where no code was found are marked as + * MONGOC_ERROR_QUERY_FAILURE */ case MONGOC_ERROR_QUERY_FAILURE: return NULL != strstr (error->message, "not master or secondary") || NULL != strstr (error->message, "node is recovering"); @@ -325,3 +316,14 @@ _mongoc_error_is_network (const bson_error_t *error) return false; } + +bool +_mongoc_error_is_auth (const bson_error_t *error) +{ + if (!error) { + return false; + } + + return error->domain == MONGOC_ERROR_CLIENT && + error->code == MONGOC_ERROR_CLIENT_AUTHENTICATE; +} diff --git a/src/mongoc/mongoc-error.h b/src/mongoc/mongoc-error.h index 274411c4..52a289e7 100644 --- a/src/mongoc/mongoc-error.h +++ b/src/mongoc/mongoc-error.h @@ -49,7 +49,9 @@ typedef enum { MONGOC_ERROR_SERVER, /* Error API Version 2 only */ MONGOC_ERROR_TRANSACTION, MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION, /* An error coming from libmongocrypt */ - MONGOC_ERROR_POOL + MONGOC_ERROR_POOL, + MONGOC_ERROR_AZURE, + MONGOC_ERROR_GCP } mongoc_error_domain_t; @@ -134,6 +136,11 @@ typedef enum { MONGOC_ERROR_POOL_API_TOO_LATE, MONGOC_ERROR_CLIENT_INVALID_LOAD_BALANCER, + + /* An error related to either GCP metadata or Azure IMDS server */ + MONGOC_ERROR_KMS_SERVER_HTTP, + MONGOC_ERROR_KMS_SERVER_BAD_JSON, + } mongoc_error_code_t; MONGOC_EXPORT (bool) diff --git a/src/mongoc/mongoc-flags.c b/src/mongoc/mongoc-flags.c new file mode 100644 index 00000000..1393e499 --- /dev/null +++ b/src/mongoc/mongoc-flags.c @@ -0,0 +1,79 @@ +/* + * Copyright 2023-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mongoc-flags.h" + +#include "mongoc-compression-private.h" +#include "mongoc-flags-private.h" + +#include "mcd-rpc.h" + +#include + +// Document and ensure consistency between equivalent macros in mcd-rpc and +// libmongoc. + +BSON_STATIC_ASSERT (MONGOC_OP_COMPRESSED_COMPRESSOR_ID_NOOP == + MONGOC_COMPRESSOR_NOOP_ID); +BSON_STATIC_ASSERT (MONGOC_OP_COMPRESSED_COMPRESSOR_ID_SNAPPY == + MONGOC_COMPRESSOR_SNAPPY_ID); +BSON_STATIC_ASSERT (MONGOC_OP_COMPRESSED_COMPRESSOR_ID_ZLIB == + MONGOC_COMPRESSOR_ZLIB_ID); +BSON_STATIC_ASSERT (MONGOC_OP_COMPRESSED_COMPRESSOR_ID_ZSTD == + MONGOC_COMPRESSOR_ZSTD_ID); + +BSON_STATIC_ASSERT (MONGOC_OP_MSG_FLAG_NONE == MONGOC_MSG_NONE); +BSON_STATIC_ASSERT (MONGOC_OP_MSG_FLAG_CHECKSUM_PRESENT == + MONGOC_MSG_CHECKSUM_PRESENT); +BSON_STATIC_ASSERT (MONGOC_OP_MSG_FLAG_MORE_TO_COME == MONGOC_MSG_MORE_TO_COME); +BSON_STATIC_ASSERT (MONGOC_OP_MSG_FLAG_EXHAUST_ALLOWED == + MONGOC_MSG_EXHAUST_ALLOWED); + +BSON_STATIC_ASSERT (MONGOC_OP_REPLY_RESPONSE_FLAG_NONE == MONGOC_REPLY_NONE); +BSON_STATIC_ASSERT (MONGOC_OP_REPLY_RESPONSE_FLAG_CURSOR_NOT_FOUND == + MONGOC_REPLY_CURSOR_NOT_FOUND); +BSON_STATIC_ASSERT (MONGOC_OP_REPLY_RESPONSE_FLAG_QUERY_FAILURE == + MONGOC_REPLY_QUERY_FAILURE); +BSON_STATIC_ASSERT (MONGOC_OP_REPLY_RESPONSE_FLAG_SHARD_CONFIG_STALE == + MONGOC_REPLY_SHARD_CONFIG_STALE); +BSON_STATIC_ASSERT (MONGOC_OP_REPLY_RESPONSE_FLAG_AWAIT_CAPABLE == + MONGOC_REPLY_AWAIT_CAPABLE); + +BSON_STATIC_ASSERT (MONGOC_OP_UPDATE_FLAG_NONE == MONGOC_UPDATE_NONE); +BSON_STATIC_ASSERT (MONGOC_OP_UPDATE_FLAG_UPSERT == MONGOC_UPDATE_UPSERT); +BSON_STATIC_ASSERT (MONGOC_OP_UPDATE_FLAG_MULTI_UPDATE == + MONGOC_UPDATE_MULTI_UPDATE); + +BSON_STATIC_ASSERT (MONGOC_OP_INSERT_FLAG_NONE == MONGOC_INSERT_NONE); +BSON_STATIC_ASSERT (MONGOC_OP_INSERT_FLAG_CONTINUE_ON_ERROR == + MONGOC_INSERT_CONTINUE_ON_ERROR); + +BSON_STATIC_ASSERT (MONGOC_OP_QUERY_FLAG_NONE == MONGOC_QUERY_NONE); +BSON_STATIC_ASSERT (MONGOC_OP_QUERY_FLAG_TAILABLE_CURSOR == + MONGOC_QUERY_TAILABLE_CURSOR); +BSON_STATIC_ASSERT (MONGOC_OP_QUERY_FLAG_SECONDARY_OK == + MONGOC_QUERY_SECONDARY_OK); +BSON_STATIC_ASSERT (MONGOC_OP_QUERY_FLAG_OPLOG_REPLAY == + MONGOC_QUERY_OPLOG_REPLAY); +BSON_STATIC_ASSERT (MONGOC_OP_QUERY_FLAG_NO_CURSOR_TIMEOUT == + MONGOC_QUERY_NO_CURSOR_TIMEOUT); +BSON_STATIC_ASSERT (MONGOC_OP_QUERY_FLAG_AWAIT_DATA == MONGOC_QUERY_AWAIT_DATA); +BSON_STATIC_ASSERT (MONGOC_OP_QUERY_FLAG_EXHAUST == MONGOC_QUERY_EXHAUST); +BSON_STATIC_ASSERT (MONGOC_OP_QUERY_FLAG_PARTIAL == MONGOC_QUERY_PARTIAL); + +BSON_STATIC_ASSERT (MONGOC_OP_DELETE_FLAG_NONE == MONGOC_DELETE_NONE); +BSON_STATIC_ASSERT (MONGOC_OP_DELETE_FLAG_SINGLE_REMOVE == + MONGOC_DELETE_SINGLE_REMOVE); diff --git a/src/mongoc/mongoc-gridfs-bucket-file-private.h b/src/mongoc/mongoc-gridfs-bucket-file-private.h index fcdc9677..e4d599cf 100644 --- a/src/mongoc/mongoc-gridfs-bucket-file-private.h +++ b/src/mongoc/mongoc-gridfs-bucket-file-private.h @@ -46,7 +46,7 @@ typedef struct { /* for reading */ mongoc_cursor_t *cursor; - int32_t bytes_read; + size_t bytes_read; bool finished; /* Error */ diff --git a/src/mongoc/mongoc-gridfs-bucket-file.c b/src/mongoc/mongoc-gridfs-bucket-file.c index 5460ee7c..425b8c80 100644 --- a/src/mongoc/mongoc-gridfs-bucket-file.c +++ b/src/mongoc/mongoc-gridfs-bucket-file.c @@ -312,7 +312,7 @@ _mongoc_gridfs_bucket_read_chunk (mongoc_gridfs_bucket_file_t *file) memcpy (file->buffer, data, data_len); file->in_buffer = data_len; - file->bytes_read = 0; + file->bytes_read = 0u; file->curr_chunk++; return true; @@ -323,19 +323,11 @@ _mongoc_gridfs_bucket_file_writev (mongoc_gridfs_bucket_file_t *file, const mongoc_iovec_t *iov, size_t iovcnt) { - uint32_t total; - size_t bytes_available; - size_t space_available; - int32_t written_this_iov; - size_t to_write; - size_t i; - bool r; - BSON_ASSERT (file); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); - total = 0; + size_t total = 0; if (file->err.code) { return -1; @@ -350,8 +342,7 @@ _mongoc_gridfs_bucket_file_writev (mongoc_gridfs_bucket_file_t *file, } if (!file->bucket->indexed) { - r = _mongoc_gridfs_bucket_create_indexes (file->bucket, &file->err); - if (!r) { + if (!_mongoc_gridfs_bucket_create_indexes (file->bucket, &file->err)) { /* Error is set on file. */ return -1; } else { @@ -359,32 +350,34 @@ _mongoc_gridfs_bucket_file_writev (mongoc_gridfs_bucket_file_t *file, } } - for (i = 0; i < iovcnt; i++) { - written_this_iov = 0; + BSON_ASSERT (bson_in_range_signed (size_t, file->chunk_size)); + const size_t chunk_size = (size_t) file->chunk_size; + + for (size_t i = 0u; i < iovcnt; i++) { + size_t written_this_iov = 0u; while (written_this_iov < iov[i].iov_len) { - bytes_available = iov[i].iov_len - written_this_iov; - space_available = file->chunk_size - file->in_buffer; - to_write = _mongoc_min (bytes_available, space_available); + const size_t bytes_available = iov[i].iov_len - written_this_iov; + const size_t space_available = chunk_size - file->in_buffer; + const size_t to_write = _mongoc_min (bytes_available, space_available); + memcpy (file->buffer + file->in_buffer, -#ifndef _WIN32 - (char *) -#endif - iov[i] - .iov_base + - written_this_iov, + ((char *) iov[i].iov_base) + written_this_iov, to_write); + file->in_buffer += to_write; written_this_iov += to_write; total += to_write; - if (file->in_buffer == file->chunk_size) { + + if (file->in_buffer == chunk_size) { /* Buffer is filled, write the chunk */ _mongoc_gridfs_bucket_write_chunk (file); } } } - return total; + BSON_ASSERT (bson_in_range_unsigned (ssize_t, total)); + return (ssize_t) total; } ssize_t @@ -392,20 +385,10 @@ _mongoc_gridfs_bucket_file_readv (mongoc_gridfs_bucket_file_t *file, mongoc_iovec_t *iov, size_t iovcnt) { - uint32_t total; - size_t bytes_available; - size_t space_available; - int32_t read_this_iov; - size_t to_read; - bool r; - size_t i; - BSON_ASSERT (file); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); - total = 0; - if (file->err.code) { return -1; } @@ -414,42 +397,42 @@ _mongoc_gridfs_bucket_file_readv (mongoc_gridfs_bucket_file_t *file, return 0; } - for (i = 0; i < iovcnt; i++) { - read_this_iov = 0; + size_t total = 0u; + + for (size_t i = 0u; i < iovcnt; i++) { + size_t read_this_iov = 0u; while (read_this_iov < iov[i].iov_len) { - bytes_available = file->in_buffer - file->bytes_read; - space_available = iov[i].iov_len - read_this_iov; - to_read = _mongoc_min (bytes_available, space_available); - memcpy ( -#ifndef _WIN32 - (char *) -#endif - iov[i] - .iov_base + - read_this_iov, - file->buffer + file->bytes_read, - to_read); + const size_t bytes_available = file->in_buffer - file->bytes_read; + const size_t space_available = iov[i].iov_len - read_this_iov; + const size_t to_read = _mongoc_min (bytes_available, space_available); + + memcpy (((char *) iov[i].iov_base) + read_this_iov, + file->buffer + file->bytes_read, + to_read); + file->bytes_read += to_read; read_this_iov += to_read; total += to_read; + if (file->bytes_read == file->in_buffer) { /* Everything in the current chunk has been read, so read a new * chunk */ - r = _mongoc_gridfs_bucket_read_chunk (file); - if (!r) { + if (!_mongoc_gridfs_bucket_read_chunk (file)) { /* an error occured while reading the chunk */ return -1; } if (file->finished) { /* There's nothing left to read */ - RETURN (total); + BSON_ASSERT (bson_in_range_unsigned (ssize_t, total)); + RETURN ((ssize_t) total); } } } } - RETURN (total); + BSON_ASSERT (bson_in_range_unsigned (ssize_t, total)); + RETURN ((ssize_t) total); } diff --git a/src/mongoc/mongoc-gridfs-bucket.c b/src/mongoc/mongoc-gridfs-bucket.c index fd2ea99b..6ccacab9 100644 --- a/src/mongoc/mongoc-gridfs-bucket.c +++ b/src/mongoc/mongoc-gridfs-bucket.c @@ -161,7 +161,7 @@ mongoc_gridfs_bucket_open_upload_stream_with_id (mongoc_gridfs_bucket_t *bucket, BSON_ASSERT (filename); if (!_mongoc_gridfs_bucket_upload_opts_parse ( - NULL /* not needed. */, opts, &gridfs_opts, error)) { + bucket->files->client, opts, &gridfs_opts, error)) { _mongoc_gridfs_bucket_upload_opts_cleanup (&gridfs_opts); return NULL; } diff --git a/src/mongoc/mongoc-gridfs-file.c b/src/mongoc/mongoc-gridfs-file.c index 1fb8999d..73b91f3e 100644 --- a/src/mongoc/mongoc-gridfs-file.c +++ b/src/mongoc/mongoc-gridfs-file.c @@ -448,7 +448,7 @@ mongoc_gridfs_file_readv (mongoc_gridfs_file_t *file, BSON_ASSERT (iovcnt); /* Reading when positioned past the end does nothing */ - if (file->pos >= file->length) { + if (bson_cmp_greater_equal_us (file->pos, file->length)) { return 0; } @@ -517,7 +517,8 @@ mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, } /* When writing past the end-of-file, fill the gap with zeros */ - if (file->pos > file->length && !_mongoc_gridfs_file_extend (file)) { + if (bson_cmp_greater_us (file->pos, file->length) && + !_mongoc_gridfs_file_extend (file)) { return -1; } @@ -580,19 +581,19 @@ mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, static ssize_t _mongoc_gridfs_file_extend (mongoc_gridfs_file_t *file) { - int64_t target_length; - ssize_t diff; - ENTRY; BSON_ASSERT (file); - if (file->length >= file->pos) { + if (bson_cmp_greater_equal_su (file->length, file->pos)) { RETURN (0); } - diff = (ssize_t) (file->pos - file->length); - target_length = file->pos; + const uint64_t target_length = file->pos; + + BSON_ASSERT (bson_in_range_signed (uint64_t, file->length)); + const uint64_t diff = file->pos - (uint64_t) file->length; + if (-1 == mongoc_gridfs_file_seek (file, 0, SEEK_END)) { RETURN (-1); } @@ -603,8 +604,12 @@ _mongoc_gridfs_file_extend (mongoc_gridfs_file_t *file) } /* Set bytes until we reach the limit or fill a page */ - file->pos += _mongoc_gridfs_file_page_memset0 (file->page, - target_length - file->pos); + { + const uint64_t len = target_length - file->pos; + BSON_ASSERT (bson_in_range_unsigned (uint32_t, len)); + file->pos += + _mongoc_gridfs_file_page_memset0 (file->page, (uint32_t) len); + } if (file->pos == target_length) { /* We're done */ @@ -615,10 +620,12 @@ _mongoc_gridfs_file_extend (mongoc_gridfs_file_t *file) } } - file->length = target_length; + BSON_ASSERT (bson_in_range_unsigned (int64_t, target_length)); + file->length = (int64_t) target_length; file->is_dirty = true; - RETURN (diff); + BSON_ASSERT (bson_in_range_unsigned (ssize_t, diff)); + RETURN ((ssize_t) diff); } @@ -770,7 +777,6 @@ _mongoc_gridfs_file_refresh_page (mongoc_gridfs_file_t *file) bson_t query; bson_t child; bson_t opts; - const bson_t *chunk; const char *key; bson_iter_t iter; int64_t existing_chunks; @@ -836,9 +842,11 @@ _mongoc_gridfs_file_refresh_page (mongoc_gridfs_file_t *file) BSON_ASSERT (file->cursor); } + const bson_t *chunk = NULL; + /* we might have had a cursor before, then seeked ahead past a chunk. * iterate until we're on the right chunk */ - while (file->cursor_range[0] <= file->n) { + while (bson_cmp_less_equal_us (file->cursor_range[0], file->n)) { if (!mongoc_cursor_next (file->cursor, &chunk)) { /* copy cursor error; if there's none, we're missing a chunk */ if (!mongoc_cursor_error (file->cursor, &file->error)) { @@ -864,6 +872,18 @@ _mongoc_gridfs_file_refresh_page (mongoc_gridfs_file_t *file) } } else if (strcmp (key, "data") == 0) { bson_iter_binary (&iter, NULL, &len, &data); + // If this not the last chunk, ensure length is equal to chunk size. + bool is_last_chunk = ((file->n + 1) == existing_chunks); + // If this is not the last chunk, error. + if (!is_last_chunk && bson_cmp_not_equal_us (len, file->chunk_size)) { + bson_set_error (&file->error, + MONGOC_ERROR_GRIDFS, + MONGOC_ERROR_GRIDFS_CORRUPT, + "corrupt chunk number %" PRId32 ": not equal to chunk size: %" PRId32, + file->n, + file->chunk_size); + RETURN (0); + } } else { /* Unexpected key. This should never happen */ RETURN (0); @@ -879,17 +899,18 @@ _mongoc_gridfs_file_refresh_page (mongoc_gridfs_file_t *file) bson_set_error (&file->error, MONGOC_ERROR_GRIDFS, MONGOC_ERROR_GRIDFS_CHUNK_MISSING, - "corrupt chunk number %" PRId32, + "corrupt chunk number %" PRId32 ": no data", file->n); RETURN (0); } - if (len > file->chunk_size) { + if (bson_cmp_greater_us (len, file->chunk_size)) { bson_set_error (&file->error, MONGOC_ERROR_GRIDFS, MONGOC_ERROR_GRIDFS_CORRUPT, - "corrupt chunk number %" PRId32 ": bad size", - file->n); + "corrupt chunk number %" PRId32 ": greater than chunk size: %" PRId32, + file->n, + file->chunk_size); RETURN (0); } @@ -944,7 +965,8 @@ mongoc_gridfs_file_seek (mongoc_gridfs_file_t *file, int64_t delta, int whence) offset = delta; break; case SEEK_CUR: - offset = file->pos + delta; + BSON_ASSERT (bson_in_range_unsigned (int64_t, file->pos)); + offset = (int64_t) file->pos + delta; break; case SEEK_END: offset = file->length + delta; @@ -978,12 +1000,17 @@ mongoc_gridfs_file_seek (mongoc_gridfs_file_t *file, int64_t delta, int whence) /** we'll pick up the seek when we fetch a page on the next action. We * lazily load */ } else if (file->page) { - BSON_ASSERT ( - _mongoc_gridfs_file_page_seek (file->page, offset % file->chunk_size)); + const int64_t n = offset % file->chunk_size; + BSON_ASSERT (bson_in_range_signed (uint32_t, n)); + BSON_ASSERT (_mongoc_gridfs_file_page_seek (file->page, (uint32_t) n)); } - file->pos = offset; - file->n = file->pos / file->chunk_size; + file->pos = (uint64_t) offset; + + BSON_ASSERT (bson_in_range_signed (uint64_t, file->chunk_size)); + const uint64_t n = file->pos / (uint64_t) file->chunk_size; + BSON_ASSERT (bson_in_range_unsigned (int32_t, n)); + file->n = (int32_t) n; return 0; } diff --git a/src/mongoc/mongoc-gridfs.c b/src/mongoc/mongoc-gridfs.c index 6b485e7e..39f8bef8 100644 --- a/src/mongoc/mongoc-gridfs.c +++ b/src/mongoc/mongoc-gridfs.c @@ -104,7 +104,7 @@ _mongoc_gridfs_new (mongoc_client_t *client, ENTRY; - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (db); if (!prefix) { diff --git a/src/mongoc/mongoc-handshake-private.h b/src/mongoc/mongoc-handshake-private.h index 8da55ebc..d138c91f 100644 --- a/src/mongoc/mongoc-handshake-private.h +++ b/src/mongoc/mongoc-handshake-private.h @@ -46,45 +46,60 @@ BSON_BEGIN_DECLS /* When adding a new field to mongoc-config.h.in, update this! */ typedef enum { - /* The bit position (from the RHS) of each config flag. Do not reorder. */ + /* The bit position (from the RHS) of each config flag. Do not reorder or + change values. */ MONGOC_MD_FLAG_ENABLE_CRYPTO = 0, - MONGOC_MD_FLAG_ENABLE_CRYPTO_CNG, - MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO, - MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO, - MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE, - MONGOC_MD_FLAG_ENABLE_SASL, - MONGOC_MD_FLAG_ENABLE_SSL, - MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL, - MONGOC_MD_FLAG_ENABLE_SSL_SECURE_CHANNEL, - MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT, - MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES, - MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE, - MONGOC_MD_FLAG_HAVE_WEAK_SYMBOLS, - MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS, - MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL, - MONGOC_MD_FLAG_ENABLE_SASL_CYRUS, - MONGOC_MD_FLAG_ENABLE_SASL_SSPI, - MONGOC_MD_FLAG_HAVE_SOCKLEN, - MONGOC_MD_FLAG_ENABLE_COMPRESSION, - MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY, - MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB, - MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI_UNUSED, /* CDRIVER-2654 removed this . */ - MONGOC_MD_FLAG_ENABLE_RES_NSEARCH, - MONGOC_MD_FLAG_ENABLE_RES_NDESTROY, - MONGOC_MD_FLAG_ENABLE_RES_NCLOSE, - MONGOC_MD_FLAG_ENABLE_RES_SEARCH, - MONGOC_MD_FLAG_ENABLE_DNSAPI, - MONGOC_MD_FLAG_ENABLE_RDTSCP, - MONGOC_MD_FLAG_HAVE_SCHED_GETCPU, - MONGOC_MD_FLAG_ENABLE_SHM_COUNTERS, - MONGOC_MD_FLAG_TRACE, - MONGOC_MD_FLAG_ENABLE_ICU, - MONGOC_MD_FLAG_ENABLE_CLIENT_SIDE_ENCRYPTION, - MONGOC_MD_FLAG_ENABLE_MONGODB_AWS_AUTH, + MONGOC_MD_FLAG_ENABLE_CRYPTO_CNG = 1, + MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO = 2, + MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO = 3, + MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE = 4, + MONGOC_MD_FLAG_ENABLE_SASL = 5, + MONGOC_MD_FLAG_ENABLE_SSL = 6, + MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL = 7, + MONGOC_MD_FLAG_ENABLE_SSL_SECURE_CHANNEL = 8, + MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT = 9, + MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES = 10, + MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE = 11, + MONGOC_MD_FLAG_HAVE_WEAK_SYMBOLS = 12, + MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS = 13, + MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL = 14, + MONGOC_MD_FLAG_ENABLE_SASL_CYRUS = 15, + MONGOC_MD_FLAG_ENABLE_SASL_SSPI = 16, + MONGOC_MD_FLAG_HAVE_SOCKLEN = 17, + MONGOC_MD_FLAG_ENABLE_COMPRESSION = 18, + MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY = 19, + MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB = 20, + MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI_UNUSED = + 21, /* CDRIVER-2654 removed this . */ + MONGOC_MD_FLAG_ENABLE_RES_NSEARCH = 22, + MONGOC_MD_FLAG_ENABLE_RES_NDESTROY = 23, + MONGOC_MD_FLAG_ENABLE_RES_NCLOSE = 24, + MONGOC_MD_FLAG_ENABLE_RES_SEARCH = 25, + MONGOC_MD_FLAG_ENABLE_DNSAPI = 26, + MONGOC_MD_FLAG_ENABLE_RDTSCP = 27, + MONGOC_MD_FLAG_HAVE_SCHED_GETCPU = 28, + MONGOC_MD_FLAG_ENABLE_SHM_COUNTERS = 29, + MONGOC_MD_FLAG_TRACE = 30, + MONGOC_MD_FLAG_ENABLE_ICU_UNUSED = 31, + MONGOC_MD_FLAG_ENABLE_CLIENT_SIDE_ENCRYPTION = 32, + MONGOC_MD_FLAG_ENABLE_MONGODB_AWS_AUTH = 33, + MONGOC_MD_FLAG_ENABLE_SRV = 34, /* Add additional config flags here, above LAST_MONGOC_MD_FLAG. */ LAST_MONGOC_MD_FLAG } mongoc_handshake_config_flag_bit_t; +typedef enum { + MONGOC_HANDSHAKE_ENV_NONE, + MONGOC_HANDSHAKE_ENV_AWS, + MONGOC_HANDSHAKE_ENV_VERCEL, + MONGOC_HANDSHAKE_ENV_GCP, + MONGOC_HANDSHAKE_ENV_AZURE +} mongoc_handshake_env_t; + +typedef struct _optional_int32 { + bool set; + int32_t value; +} optional_int32; typedef struct _mongoc_handshake_t { char *os_type; @@ -98,6 +113,11 @@ typedef struct _mongoc_handshake_t { char *compiler_info; char *flags; + mongoc_handshake_env_t env; + optional_int32 env_timeout_sec; + optional_int32 env_memory_mb; + char *env_region; + bool frozen; } mongoc_handshake_t; @@ -107,9 +127,8 @@ _mongoc_handshake_init (void); void _mongoc_handshake_cleanup (void); -bool -_mongoc_handshake_build_doc_with_application (bson_t *doc, - const char *application); +bson_t * +_mongoc_handshake_build_doc_with_application (const char *application); void _mongoc_handshake_freeze (void); diff --git a/src/mongoc/mongoc-handshake.c b/src/mongoc/mongoc-handshake.c index fc08285c..6b3fc28e 100644 --- a/src/mongoc/mongoc-handshake.c +++ b/src/mongoc/mongoc-handshake.c @@ -36,6 +36,8 @@ #include "mongoc-version.h" #include "mongoc-util-private.h" +#include + /* * Global handshake data instance. Initialized at startup from mongoc_init * @@ -61,14 +63,10 @@ _set_bit (uint8_t *bf, uint32_t byte_count, uint32_t bit) char * _mongoc_handshake_get_config_hex_string (void) { - uint32_t byte_count; - uint8_t *bf; - bson_string_t *str; - int i; - - byte_count = (LAST_MONGOC_MD_FLAG + 7) / 8; /* ceil (num_bits / 8) */ + const uint32_t byte_count = + (LAST_MONGOC_MD_FLAG + 7) / 8; /* ceil (num_bits / 8) */ /* allocate enough bytes to fit all config bits. */ - bf = (uint8_t *) bson_malloc0 (byte_count); + uint8_t *const bf = (uint8_t *) bson_malloc0 (byte_count); #ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL _set_bit (bf, byte_count, MONGOC_ENABLE_SSL_SECURE_CHANNEL); @@ -186,10 +184,6 @@ _mongoc_handshake_get_config_hex_string (void) _set_bit (bf, byte_count, MONGOC_MD_FLAG_TRACE); } -#ifdef MONGOC_ENABLE_ICU - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_ICU); -#endif - #ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CLIENT_SIDE_ENCRYPTION); #endif @@ -198,8 +192,12 @@ _mongoc_handshake_get_config_hex_string (void) _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_MONGODB_AWS_AUTH); #endif - str = bson_string_new ("0x"); - for (i = 0; i < byte_count; i++) { + if (MONGOC_SRV_ENABLED) { + _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SRV); + } + + bson_string_t *const str = bson_string_new ("0x"); + for (uint32_t i = 0u; i < byte_count; i++) { bson_string_append_printf (str, "%02x", bf[i]); } bson_free (bf); @@ -295,7 +293,15 @@ _get_os_version (void) ZeroMemory (&osvi, sizeof (OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - if (GetVersionEx (&osvi)) { +#if defined(_MSC_VER) + // CDRIVER-4263: GetVersionEx is deprecated. +#pragma warning(suppress : 4996) + const BOOL res = GetVersionEx (&osvi); +#else + const BOOL res = GetVersionEx (&osvi); +#endif + + if (res) { bson_snprintf (ret, HANDSHAKE_OS_VERSION_MAX, "%lu.%lu (%lu)", @@ -378,6 +384,93 @@ _set_platform_string (mongoc_handshake_t *handshake) handshake->platform = bson_string_free (str, false); } +static void +_free_env_info (mongoc_handshake_t *handshake) +{ + bson_free (handshake->env_region); +} + +static void +_get_env_info (mongoc_handshake_t *handshake) +{ + char *aws_env = _mongoc_getenv ("AWS_EXECUTION_ENV"); + char *aws_lambda = _mongoc_getenv ("AWS_LAMBDA_RUNTIME_API"); + char *vercel_env = _mongoc_getenv ("VERCEL"); + char *azure_env = _mongoc_getenv ("FUNCTIONS_WORKER_RUNTIME"); + char *gcp_env = _mongoc_getenv ("K_SERVICE"); + char *memory_str = NULL; + char *timeout_str = NULL; + char *region_str = NULL; + + bool is_aws = (aws_env && strlen (aws_env) && + (aws_env == strstr (aws_env, "AWS_Lambda_"))) || + (aws_lambda && strlen (aws_lambda)); + bool is_vercel = vercel_env && strlen (vercel_env); + bool is_azure = azure_env && strlen (azure_env); + bool is_gcp = gcp_env && strlen (gcp_env); + + handshake->env = MONGOC_HANDSHAKE_ENV_NONE; + handshake->env_region = NULL; + handshake->env_memory_mb.set = false; + handshake->env_timeout_sec.set = false; + + if ((is_aws || is_vercel) + is_azure + is_gcp != 1) { + goto cleanup; + } + + if (is_aws && !is_vercel) { + handshake->env = MONGOC_HANDSHAKE_ENV_AWS; + region_str = _mongoc_getenv ("AWS_REGION"); + memory_str = _mongoc_getenv ("AWS_LAMBDA_FUNCTION_MEMORY_SIZE"); + } else if (is_vercel) { + handshake->env = MONGOC_HANDSHAKE_ENV_VERCEL; + region_str = _mongoc_getenv ("VERCEL_REGION"); + } else if (is_gcp) { + handshake->env = MONGOC_HANDSHAKE_ENV_GCP; + region_str = _mongoc_getenv ("FUNCTION_REGION"); + memory_str = _mongoc_getenv ("FUNCTION_MEMORY_MB"); + timeout_str = _mongoc_getenv ("FUNCTION_TIMEOUT_SEC"); + } else if (is_azure) { + handshake->env = MONGOC_HANDSHAKE_ENV_AZURE; + } + + if (memory_str) { + char *endptr; + int64_t env_memory_mb = bson_ascii_strtoll (memory_str, &endptr, 10); + bool parse_ok = endptr == memory_str + (strlen (memory_str)); + bool in_range = bson_in_range_int32_t_signed (env_memory_mb); + + if (parse_ok && in_range) { + handshake->env_memory_mb.set = true; + handshake->env_memory_mb.value = (int32_t) env_memory_mb; + } + } + if (timeout_str) { + char *endptr; + int64_t env_timeout_sec = bson_ascii_strtoll (timeout_str, &endptr, 10); + bool parse_ok = endptr == timeout_str + (strlen (timeout_str)); + bool in_range = bson_in_range_int32_t_signed (env_timeout_sec); + + if (parse_ok && in_range) { + handshake->env_timeout_sec.set = true; + handshake->env_timeout_sec.value = (int32_t) env_timeout_sec; + } + } + if (region_str && strlen (region_str)) { + handshake->env_region = bson_strdup (region_str); + } + +cleanup: + bson_free (aws_env); + bson_free (aws_lambda); + bson_free (vercel_env); + bson_free (azure_env); + bson_free (gcp_env); + bson_free (memory_str); + bson_free (timeout_str); + bson_free (region_str); +} + static void _set_compiler_info (mongoc_handshake_t *handshake) { @@ -440,6 +533,7 @@ _mongoc_handshake_init (void) _get_system_info (_mongoc_handshake_get ()); _get_driver_info (_mongoc_handshake_get ()); _set_platform_string (_mongoc_handshake_get ()); + _get_env_info (_mongoc_handshake_get ()); _set_compiler_info (_mongoc_handshake_get ()); _set_flags (_mongoc_handshake_get ()); @@ -450,24 +544,25 @@ _mongoc_handshake_init (void) void _mongoc_handshake_cleanup (void) { - _free_system_info (_mongoc_handshake_get ()); - _free_driver_info (_mongoc_handshake_get ()); - _free_platform_string (_mongoc_handshake_get ()); + mongoc_handshake_t *h = _mongoc_handshake_get (); + _free_system_info (h); + _free_driver_info (h); + _free_platform_string (h); + _free_env_info (h); + *h = (mongoc_handshake_t){0}; bson_mutex_destroy (&gHandshakeLock); } static void -_append_platform_field (bson_t *doc, const char *platform) +_append_platform_field (bson_t *doc, const char *platform, bool truncate) { - int max_platform_str_size; - char *compiler_info = _mongoc_handshake_get ()->compiler_info; char *flags = _mongoc_handshake_get ()->flags; bson_string_t *combined_platform = bson_string_new (platform); /* Compute space left for platform field */ - max_platform_str_size = + const int max_platform_str_size = HANDSHAKE_MAX_SIZE - ((int) doc->len + /* 1 byte for utf8 tag */ 1 + @@ -478,89 +573,176 @@ _append_platform_field (bson_t *doc, const char *platform) /* 4 bytes for length of string */ 4); - if (max_platform_str_size <= 0) { + if (truncate && max_platform_str_size <= 0) { bson_string_free (combined_platform, true); return; } /* We opt to drop compiler info and flags if they can't fit, while the * platform information is truncated - * Try to drop flags first, and if there is still not enough space also drop - * compiler info */ - if (max_platform_str_size > - combined_platform->len + strlen (compiler_info) + 1) { + * Try to drop flags first, and if there is still not enough space also + * drop compiler info */ + if (!truncate || bson_cmp_greater_equal_su ( + max_platform_str_size, + combined_platform->len + strlen (compiler_info) + 1u)) { bson_string_append (combined_platform, compiler_info); } - if (max_platform_str_size > combined_platform->len + strlen (flags) + 1) { + if (!truncate || bson_cmp_greater_equal_su (max_platform_str_size, + combined_platform->len + + strlen (flags) + 1u)) { bson_string_append (combined_platform, flags); } /* We use the flags_index field to check if the CLAGS/LDFLAGS need to be * truncated, and if so we drop them altogether */ + BSON_ASSERT (bson_in_range_unsigned (int, combined_platform->len)); + int length = truncate ? BSON_MIN (max_platform_str_size - 1, + (int) combined_platform->len) + : -1; bson_append_utf8 ( - doc, - HANDSHAKE_PLATFORM_FIELD, - -1, - combined_platform->str, - BSON_MIN (max_platform_str_size - 1, combined_platform->len)); + doc, HANDSHAKE_PLATFORM_FIELD, -1, combined_platform->str, length); bson_string_free (combined_platform, true); - BSON_ASSERT (doc->len <= HANDSHAKE_MAX_SIZE); } -/* - * Return true if we build the document, and it's not too big - * false if there's no way to prevent the doc from being too big. In this - * case, the caller shouldn't include it with hello - */ -bool -_mongoc_handshake_build_doc_with_application (bson_t *doc, const char *appname) +static bool +_get_subdoc_static (bson_t *doc, char *subdoc_name, bson_t *out) { - const mongoc_handshake_t *md = _mongoc_handshake_get (); - bson_t child; - - if (appname) { - BSON_APPEND_DOCUMENT_BEGIN (doc, "application", &child); - BSON_APPEND_UTF8 (&child, "name", appname); - bson_append_document_end (doc, &child); + bson_iter_t iter; + if (bson_iter_init_find (&iter, doc, subdoc_name) && + BSON_ITER_HOLDS_DOCUMENT (&iter)) { + uint32_t len; + const uint8_t *data; + bson_iter_document (&iter, &len, &data); + BSON_ASSERT (bson_init_static (out, data, len)); + + return true; } + return false; +} - BSON_APPEND_DOCUMENT_BEGIN (doc, "driver", &child); - BSON_APPEND_UTF8 (&child, "name", md->driver_name); - BSON_APPEND_UTF8 (&child, "version", md->driver_version); - bson_append_document_end (doc, &child); +static bool +_truncate_handshake (bson_t **doc) +{ + if ((*doc)->len > HANDSHAKE_MAX_SIZE) { + bson_t env_doc; + if (_get_subdoc_static (*doc, "env", &env_doc)) { + bson_t *new_env = bson_new (); + bson_copy_to_including_noinit (&env_doc, new_env, "name", NULL); + + bson_t *new_doc = bson_new (); + bson_copy_to_excluding_noinit (*doc, new_doc, "env", NULL); + + bson_append_document (new_doc, "env", -1, new_env); + bson_destroy (new_env); + bson_destroy (*doc); + *doc = new_doc; + } + } - BSON_APPEND_DOCUMENT_BEGIN (doc, "os", &child); + if ((*doc)->len > HANDSHAKE_MAX_SIZE) { + bson_t os_doc; + if (_get_subdoc_static (*doc, "os", &os_doc)) { + bson_t *new_os = bson_new (); + bson_copy_to_including_noinit (&os_doc, new_os, "type", NULL); - BSON_ASSERT (md->os_type); - BSON_APPEND_UTF8 (&child, "type", md->os_type); + bson_t *new_doc = bson_new (); + bson_copy_to_excluding_noinit (*doc, new_doc, "os", NULL); - if (md->os_name) { - BSON_APPEND_UTF8 (&child, "name", md->os_name); + bson_append_document (new_doc, "os", -1, new_os); + bson_destroy (new_os); + bson_destroy (*doc); + *doc = new_doc; + } } - if (md->os_version) { - BSON_APPEND_UTF8 (&child, "version", md->os_version); + if ((*doc)->len > HANDSHAKE_MAX_SIZE) { + bson_t *new_doc = bson_new (); + bson_copy_to_excluding_noinit (*doc, new_doc, "env", NULL); + bson_destroy (*doc); + *doc = new_doc; } - if (md->os_architecture) { - BSON_APPEND_UTF8 (&child, "architecture", md->os_architecture); + const mongoc_handshake_t *md = _mongoc_handshake_get (); + if ((*doc)->len > HANDSHAKE_MAX_SIZE && md->platform) { + bson_t *new_doc = bson_new (); + bson_copy_to_excluding_noinit (*doc, new_doc, "platform", NULL); + _append_platform_field (new_doc, md->platform, true); + bson_destroy (*doc); + *doc = new_doc; } - bson_append_document_end (doc, &child); + return (*doc)->len <= HANDSHAKE_MAX_SIZE; +} - if (doc->len > HANDSHAKE_MAX_SIZE) { - /* We've done all we can possibly do to ensure the current - * document is below the maxsize, so if it overflows there is - * nothing else we can do, so we fail */ - return false; +/* + * Return true if we build the document, and it's not too big + * false if there's no way to prevent the doc from being too big. In this + * case, the caller shouldn't include it with hello + */ +bson_t * +_mongoc_handshake_build_doc_with_application (const char *appname) +{ + const mongoc_handshake_t *md = _mongoc_handshake_get (); + char *env_name = NULL; + switch (md->env) { + case MONGOC_HANDSHAKE_ENV_AWS: + env_name = "aws.lambda"; + break; + case MONGOC_HANDSHAKE_ENV_GCP: + env_name = "gcp.func"; + break; + case MONGOC_HANDSHAKE_ENV_AZURE: + env_name = "azure.func"; + break; + case MONGOC_HANDSHAKE_ENV_VERCEL: + env_name = "vercel"; + break; + case MONGOC_HANDSHAKE_ENV_NONE: + env_name = NULL; + break; + default: + break; } + bson_t *doc = bson_new (); + // Optimistically include all handshake data + bsonBuildAppend ( + *doc, + if (appname, + then (kv ("application", doc (kv ("name", cstr (appname)))))), + kv ("driver", + doc (kv ("name", cstr (md->driver_name)), + kv ("version", cstr (md->driver_version)))), + kv ( + "os", + doc (kv ("type", cstr (md->os_type)), + if (md->os_name, then (kv ("name", cstr (md->os_name)))), + if (md->os_version, then (kv ("version", cstr (md->os_version)))), + if (md->os_architecture, + then (kv ("architecture", cstr (md->os_architecture)))))), + if (env_name, + then (kv ( + "env", + doc (kv ("name", cstr (env_name)), + if (md->env_timeout_sec.set, + then (kv ("timeout_sec", + int32 (md->env_timeout_sec.value)))), + if (md->env_memory_mb.set, + then (kv ("memory_mb", int32 (md->env_memory_mb.value)))), + if (md->env_region, + then (kv ("region", cstr (md->env_region))))))))); + if (md->platform) { - _append_platform_field (doc, md->platform); + _append_platform_field (doc, md->platform, false); } - return true; + if (_truncate_handshake (&doc)) { + return doc; + } else { + bson_destroy (doc); + return NULL; + } } void @@ -574,26 +756,28 @@ _mongoc_handshake_freeze (void) * If *s is NULL it's treated like it's an empty string. */ static void -_append_and_truncate (char **s, const char *suffix, int max_len) +_append_and_truncate (char **s, const char *suffix, size_t max_len) { char *old_str = *s; - char *prefix; - const int delim_len = (int) strlen (" / "); - int space_for_suffix; + const size_t delim_len = strlen (" / "); BSON_ASSERT_PARAM (s); BSON_ASSERT_PARAM (suffix); - prefix = old_str ? old_str : ""; + const char *const prefix = old_str ? old_str : ""; - space_for_suffix = max_len - (int) strlen (prefix) - delim_len; + const size_t required_space = strlen (prefix) + delim_len; - if (space_for_suffix <= 0) { + if (max_len <= required_space) { /* the old string already takes the whole allotted space */ return; } - *s = bson_strdup_printf ("%s / %.*s", prefix, space_for_suffix, suffix); + const size_t space_for_suffix = max_len - required_space; + BSON_ASSERT (bson_in_range_unsigned (int, space_for_suffix)); + + *s = + bson_strdup_printf ("%s / %.*s", prefix, (int) space_for_suffix, suffix); BSON_ASSERT (strlen (*s) <= max_len); bson_free (old_str); @@ -604,8 +788,8 @@ _append_and_truncate (char **s, const char *suffix, int max_len) * Set some values in our global handshake struct. These values will be sent * to the server as part of the initial connection handshake (hello). * If this function is called more than once, or after we've connected to a - * mongod, then it will do nothing and return false. It will return true if it - * successfully sets the values. + * mongod, then it will do nothing and return false. It will return true if + * it successfully sets the values. * * All arguments are optional. */ @@ -631,8 +815,9 @@ mongoc_handshake_data_append (const char *driver_name, HANDSHAKE_MAX_SIZE - (int) strlen (_mongoc_handshake_get ()->platform); if (platform) { - /* we check for an empty string as a special case to avoid an unnecessary - * delimiter being added in front of the string by _append_and_truncate */ + /* we check for an empty string as a special case to avoid an + * unnecessary delimiter being added in front of the string by + * _append_and_truncate */ if (_mongoc_handshake_get ()->platform[0] == '\0') { bson_free (_mongoc_handshake_get ()->platform); _mongoc_handshake_get ()->platform = @@ -691,22 +876,12 @@ _mongoc_handshake_parse_sasl_supported_mechs ( const bson_t *hello, mongoc_handshake_sasl_supported_mechs_t *sasl_supported_mechs) { - bson_iter_t iter; memset (sasl_supported_mechs, 0, sizeof (*sasl_supported_mechs)); - if (bson_iter_init_find (&iter, hello, "saslSupportedMechs")) { - bson_iter_t array_iter; - if (BSON_ITER_HOLDS_ARRAY (&iter) && - bson_iter_recurse (&iter, &array_iter)) { - while (bson_iter_next (&array_iter)) { - if (BSON_ITER_HOLDS_UTF8 (&array_iter)) { - const char *mechanism_name = bson_iter_utf8 (&array_iter, NULL); - if (0 == strcmp (mechanism_name, "SCRAM-SHA-256")) { - sasl_supported_mechs->scram_sha_256 = true; - } else if (0 == strcmp (mechanism_name, "SCRAM-SHA-1")) { - sasl_supported_mechs->scram_sha_1 = true; - } - } - } - } - } + bsonParse (*hello, + find (keyWithType ("saslSupportedMechs", array), + visitEach (case ( + when (strEqual ("SCRAM-SHA-256"), + do (sasl_supported_mechs->scram_sha_256 = true)), + when (strEqual ("SCRAM-SHA-1"), + do (sasl_supported_mechs->scram_sha_1 = true)))))); } diff --git a/src/mongoc/mongoc-host-list-private.h b/src/mongoc/mongoc-host-list-private.h index a64cec5d..14d47c8a 100644 --- a/src/mongoc/mongoc-host-list-private.h +++ b/src/mongoc/mongoc-host-list-private.h @@ -52,7 +52,7 @@ _mongoc_host_list_from_hostport_with_err (mongoc_host_list_t *host_list, uint16_t port, bson_error_t *error); -int +size_t _mongoc_host_list_length (const mongoc_host_list_t *list); bool diff --git a/src/mongoc/mongoc-host-list.c b/src/mongoc/mongoc-host-list.c index becef5cb..3adbb952 100644 --- a/src/mongoc/mongoc-host-list.c +++ b/src/mongoc/mongoc-host-list.c @@ -1,7 +1,7 @@ /* * Copyright 2015 MongoDB Inc. - * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * @@ -14,6 +14,8 @@ * limitations under the License. */ +#include // PRIu16 + #include "mongoc-host-list-private.h" /* strcasecmp on windows */ #include "mongoc-util-private.h" @@ -130,11 +132,11 @@ _mongoc_host_list_copy_all (const mongoc_host_list_t *src) return head; } -int +size_t _mongoc_host_list_length (const mongoc_host_list_t *list) { const mongoc_host_list_t *tmp; - int counter = 0; + size_t counter = 0u; tmp = list; while (tmp) { @@ -343,13 +345,27 @@ _mongoc_host_list_from_hostport_with_err (mongoc_host_list_t *link_, if (strchr (host, ':')) { link_->family = AF_INET6; - mongoc_lowercase (link_->host, link_->host); - bson_snprintf (link_->host_and_port, - sizeof link_->host_and_port, - "[%s]:%hu", - link_->host, - link_->port); + // Check that IPv6 literal is two less than the max to account for `[` and + // `]` added below. + if (host_len > BSON_HOST_NAME_MAX - 2) { + bson_set_error ( + error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_NAME_RESOLUTION, + "IPv6 literal provided in URI is too long, max is %d chars", + BSON_HOST_NAME_MAX - 2); + return false; + } + mongoc_lowercase (link_->host, link_->host); + int req = bson_snprintf (link_->host_and_port, + sizeof link_->host_and_port, + "[%s]:%" PRIu16, + link_->host, + link_->port); + BSON_ASSERT (bson_in_range_size_t_signed (req)); + // Use `<`, not `<=` to account for NULL byte. + BSON_ASSERT ((size_t) req < sizeof link_->host_and_port); } else if (strchr (host, '/') && strstr (host, ".sock")) { link_->family = AF_UNIX; bson_strncpy (link_->host_and_port, link_->host, host_len + 1); @@ -358,11 +374,14 @@ _mongoc_host_list_from_hostport_with_err (mongoc_host_list_t *link_, link_->family = AF_UNSPEC; mongoc_lowercase (link_->host, link_->host); - bson_snprintf (link_->host_and_port, - sizeof link_->host_and_port, - "%s:%hu", - link_->host, - link_->port); + int req = bson_snprintf (link_->host_and_port, + sizeof link_->host_and_port, + "%s:%" PRIu16, + link_->host, + link_->port); + BSON_ASSERT (bson_in_range_size_t_signed (req)); + // Use `<`, not `<=` to account for NULL byte. + BSON_ASSERT ((size_t) req < sizeof link_->host_and_port); } link_->next = NULL; diff --git a/src/mongoc/mongoc-http-private.h b/src/mongoc/mongoc-http-private.h index c5bc0532..346a6ea7 100644 --- a/src/mongoc/mongoc-http-private.h +++ b/src/mongoc/mongoc-http-private.h @@ -49,15 +49,48 @@ _mongoc_http_response_init (mongoc_http_response_t *response); void _mongoc_http_response_cleanup (mongoc_http_response_t *response); -/* - * Send an HTTP request and get a response. - * On success, returns true. - * On failure, returns false and sets error. - * If use_tls is true, then ssl_opts must be set. - * Caller must call _mongoc_http_response_cleanup on res. +/** + * @brief Render the HTTP request head based on the given HTTP parameters. + * + * @param req The request to render (required) + * @return bson_string_t* A new bson_string_t that contains the HTTP request + * head + * + * @note The request body (if applicable) is not included in the resulting + * string. + * @note The returned bson_string_t must be freed, including the internal + * segment. + */ +bson_string_t * +_mongoc_http_render_request_head (const mongoc_http_request_t *req); + + +/** + * @brief Convenience function to send an HTTP request and receive an HTTP + * response. + * + * This function only speaks HTTP 1.0, and does not maintain a persistent + * connection. It does not handle 3xx redirects nor 1xx information. + * + * @param req The request to send. Uses the "host" attribute to determine the + * HTTP peer. + * @param timeout_ms A timeout for the request, in milliseconds + * @param use_tls Whether the connection should use TLS. + * @param ssl_opts Options to control TLS (Required only if 'use_tls' is true) + * @param res Output parameter for the response. Must be uninitialized. + * Required. This object must later be destroyed with + * _mongoc_http_response_cleanup. + * @param error An output parameter for any possible errors. These are errors + * related to the HTTP transmission, and unrelated to any HTTP response. + * (Optional) + * @return true Upon success + * @return false Otherwise, and sets "error" + * + * For more transport control, the HTTP request head content can be manually + * rendered using @ref _mongo_http_render_request_head. */ bool -_mongoc_http_send (mongoc_http_request_t *req, +_mongoc_http_send (mongoc_http_request_t const *req, int timeout_ms, bool use_tls, mongoc_ssl_opt_t *ssl_opts, diff --git a/src/mongoc/mongoc-http.c b/src/mongoc/mongoc-http.c index d1d813df..eba1754c 100644 --- a/src/mongoc/mongoc-http.c +++ b/src/mongoc/mongoc-http.c @@ -21,6 +21,7 @@ #include "mongoc-stream-tls.h" #include "mongoc-stream-private.h" #include "mongoc-buffer-private.h" +#include "mcd-time.h" void _mongoc_http_request_init (mongoc_http_request_t *request) @@ -44,8 +45,59 @@ _mongoc_http_response_cleanup (mongoc_http_response_t *response) bson_free (response->body); } +bson_string_t * +_mongoc_http_render_request_head (const mongoc_http_request_t *req) +{ + BSON_ASSERT_PARAM (req); + char *path = NULL; + + // Default paths + if (!req->path) { + // Top path: + path = bson_strdup ("/"); + } else if (req->path[0] != '/') { + // Path MUST be prefixed with a separator + path = bson_strdup_printf ("/%s", req->path); + } else { + // Just copy the path + path = bson_strdup (req->path); + } + + bson_string_t *const string = bson_string_new (""); + // Set the request line + bson_string_append_printf (string, "%s %s HTTP/1.0\r\n", req->method, path); + // (We're done with the path string:) + bson_free (path); + + /* Always add Host header. */ + bson_string_append_printf (string, "Host: %s:%d\r\n", req->host, req->port); + /* Always add Connection: close header to ensure server closes connection. */ + bson_string_append_printf (string, "Connection: close\r\n"); + /* Add Content-Length if body is included. */ + if (req->body_len) { + bson_string_append_printf ( + string, "Content-Length: %d\r\n", req->body_len); + } + // Add any extra headers + if (req->extra_headers) { + bson_string_append (string, req->extra_headers); + } + + // Final terminator + bson_string_append (string, "\r\n"); + return string; +} + +static int32_t +_mongoc_http_msec_remaining (mcd_timer timer) +{ + const int64_t msec = mcd_get_milliseconds (mcd_timer_remaining (timer)); + BSON_ASSERT (bson_in_range_signed (int32_t, msec)); + return (int32_t) msec; +} + bool -_mongoc_http_send (mongoc_http_request_t *req, +_mongoc_http_send (const mongoc_http_request_t *req, int timeout_ms, bool use_tls, mongoc_ssl_opt_t *ssl_opts, @@ -56,7 +108,6 @@ _mongoc_http_send (mongoc_http_request_t *req, mongoc_host_list_t host_list; bool ret = false; mongoc_iovec_t iovec; - ssize_t bytes_read; char *path = NULL; bson_string_t *http_request = NULL; mongoc_buffer_t http_response_buf; @@ -64,6 +115,9 @@ _mongoc_http_send (mongoc_http_request_t *req, char *ptr; const char *header_delimiter = "\r\n\r\n"; + const mcd_timer timer = + mcd_timer_expire_after (mcd_milliseconds (timeout_ms)); + memset (res, 0, sizeof (*res)); _mongoc_buffer_init (&http_response_buf, NULL, 0, NULL, NULL); @@ -72,7 +126,11 @@ _mongoc_http_send (mongoc_http_request_t *req, goto fail; } - stream = mongoc_client_connect_tcp (timeout_ms, &host_list, error); + stream = mongoc_client_connect_tcp ( + // +1 to prevent passing zero as a timeout + _mongoc_http_msec_remaining (timer) + 1, + &host_list, + error); if (!stream) { bson_set_error (error, MONGOC_ERROR_STREAM, @@ -110,7 +168,7 @@ _mongoc_http_send (mongoc_http_request_t *req, stream = tls_stream; if (!mongoc_stream_tls_handshake_block ( - stream, req->host, timeout_ms, error)) { + stream, req->host, _mongoc_http_msec_remaining (timer), error)) { goto fail; } } @@ -124,45 +182,47 @@ _mongoc_http_send (mongoc_http_request_t *req, path = bson_strdup (req->path); } - http_request = bson_string_new (""); - bson_string_append_printf ( - http_request, "%s %s HTTP/1.0\r\n", req->method, path); - /* Always add Host header. */ - bson_string_append_printf (http_request, "Host: %s\r\n", req->host); - /* Always add Connection: close header to ensure server closes connection. */ - bson_string_append_printf (http_request, "Connection: close\r\n"); - /* Add Content-Length if body included. */ - if (req->body_len) { - bson_string_append_printf ( - http_request, "Content-Length: %d\r\n", req->body_len); - } - if (req->extra_headers) { - bson_string_append (http_request, req->extra_headers); - } - bson_string_append (http_request, "\r\n"); - + http_request = _mongoc_http_render_request_head (req); iovec.iov_base = http_request->str; iovec.iov_len = http_request->len; - if (!_mongoc_stream_writev_full (stream, &iovec, 1, timeout_ms, error)) { + if (!_mongoc_stream_writev_full ( + stream, &iovec, 1, _mongoc_http_msec_remaining (timer), error)) { goto fail; } - if (req->body) { + if (req->body && req->body_len) { iovec.iov_base = (void *) req->body; iovec.iov_len = req->body_len; - if (!_mongoc_stream_writev_full (stream, &iovec, 1, timeout_ms, error)) { + if (!_mongoc_stream_writev_full ( + stream, &iovec, 1, _mongoc_http_msec_remaining (timer), error)) { goto fail; } } /* Read until connection close. */ - do { - bytes_read = _mongoc_buffer_try_append_from_stream ( - &http_response_buf, stream, 512, timeout_ms); - } while (bytes_read > 0 || mongoc_stream_should_retry (stream)); + while (1) { + const ssize_t bytes_read = _mongoc_buffer_try_append_from_stream ( + &http_response_buf, + stream, + 1024 * 32, + _mongoc_http_msec_remaining (timer)); + if (mongoc_stream_should_retry (stream)) { + continue; + } + if (bytes_read <= 0) { + break; + } + if (http_response_buf.len > 1024 * 1024 * 8) { + bson_set_error (error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "HTTP response message is too large"); + goto fail; + } + } - if (bytes_read < 0 && mongoc_stream_timed_out (stream)) { + if (mongoc_stream_timed_out (stream)) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, @@ -179,6 +239,51 @@ _mongoc_http_send (mongoc_http_request_t *req, } http_response_str = (char *) http_response_buf.data; + const char *const resp_end_ptr = http_response_str + http_response_buf.len; + + + const char *proto_leader_10 = "HTTP/1.0 "; + const char *proto_leader_11 = "HTTP/1.1 "; + ptr = strstr (http_response_str, proto_leader_10); + if (!ptr) { + ptr = strstr (http_response_str, proto_leader_11); + } + + if (!ptr) { + bson_set_error ( + error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "No HTTP version leader in HTTP response. Expected '%s' or '%s'", + proto_leader_10, + proto_leader_11); + goto fail; + } + + /* Both protocol leaders have the same length. */ + ptr += strlen (proto_leader_10); + ssize_t remain = resp_end_ptr - ptr; + if (remain < 4) { + bson_set_error (error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "Short read in HTTP response"); + goto fail; + } + + char status_buf[4] = {0}; + memcpy (status_buf, ptr, 3); + char *status_endptr; + res->status = strtol (status_buf, &status_endptr, 10); + if (status_endptr != status_buf + 3) { + bson_set_error (error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "Invalid HTTP response status string %*.s", + 4, + status_buf); + goto fail; + } /* Find the end of the headers. */ ptr = strstr (http_response_str, header_delimiter); @@ -191,13 +296,19 @@ _mongoc_http_send (mongoc_http_request_t *req, goto fail; } - res->headers_len = ptr - http_response_str; - res->headers = bson_strndup (http_response_str, res->headers_len); - res->body_len = - http_response_buf.len - res->headers_len - strlen (header_delimiter); + const size_t headers_len = (size_t) (ptr - http_response_str); + BSON_ASSERT (bson_in_range_unsigned (int, headers_len)); + + const size_t body_len = + http_response_buf.len - headers_len - strlen (header_delimiter); + BSON_ASSERT (bson_in_range_unsigned (int, body_len)); + + res->headers_len = (int) headers_len; + res->headers = bson_strndup (http_response_str, (size_t) headers_len); + res->body_len = (int) body_len; /* Add a NULL character in case caller assumes NULL terminated. */ - res->body = bson_malloc0 (res->body_len + 1); - memcpy (res->body, ptr + strlen (header_delimiter), res->body_len); + res->body = bson_malloc0 (body_len + 1u); + memcpy (res->body, ptr + strlen (header_delimiter), body_len); ret = true; fail: diff --git a/src/mongoc/mongoc-init.c b/src/mongoc/mongoc-init.c index 2e662b83..739066df 100644 --- a/src/mongoc/mongoc-init.c +++ b/src/mongoc/mongoc-init.c @@ -23,6 +23,8 @@ #include "mongoc-handshake-private.h" +#include "mongoc-cluster-aws-private.h" + #ifdef MONGOC_ENABLE_SSL_OPENSSL #include "mongoc-openssl-private.h" #elif defined(MONGOC_ENABLE_SSL_LIBRESSL) @@ -51,6 +53,7 @@ #ifdef MONGOC_ENABLE_SASL_CYRUS #include +#include "mongoc-cyrus-private.h" // _mongoc_cyrus_verifyfile_cb static void * mongoc_cyrus_mutex_alloc (void) @@ -111,7 +114,11 @@ static BSON_ONCE_FUN (_mongoc_do_init) mongoc_cyrus_mutex_unlock, mongoc_cyrus_mutex_free); - status = sasl_client_init (NULL); + sasl_callback_t callbacks[] = {// Include callback to disable loading plugins. + {SASL_CB_VERIFYFILE, SASL_CALLBACK_FN (_mongoc_cyrus_verifyfile_cb), NULL}, + {SASL_CB_LIST_END}}; + + status = sasl_client_init (callbacks); BSON_ASSERT (status == SASL_OK); #endif @@ -141,10 +148,11 @@ static BSON_ONCE_FUN (_mongoc_do_init) #if defined(MONGOC_ENABLE_MONGODB_AWS_AUTH) kms_message_init (); + _mongoc_aws_credentials_cache_init (); #endif #if defined(MONGOC_ENABLE_OCSP_OPENSSL) - _mongoc_ocsp_cache_init (); + _mongoc_ocsp_cache_init (); #endif BSON_ONCE_RETURN; @@ -186,6 +194,7 @@ static BSON_ONCE_FUN (_mongoc_do_cleanup) #if defined(MONGOC_ENABLE_MONGODB_AWS_AUTH) kms_message_cleanup (); + _mongoc_aws_credentials_cache_cleanup (); #endif #if defined(MONGOC_ENABLE_OCSP_OPENSSL) diff --git a/src/mongoc/mongoc-linux-distro-scanner.c b/src/mongoc/mongoc-linux-distro-scanner.c index dc9538c7..79246532 100644 --- a/src/mongoc/mongoc-linux-distro-scanner.c +++ b/src/mongoc/mongoc-linux-distro-scanner.c @@ -67,7 +67,7 @@ _fgets_wrapper (char *buffer, size_t buffer_size, FILE *f) * This protects us from files like: * aaaaa...DISTRIB_ID=nasal demons */ - TRACE ("Found line of length %ld, bailing out", len); + TRACE ("Found line of length %zu, bailing out", len); return 0; } diff --git a/src/mongoc/mongoc-log.c b/src/mongoc/mongoc-log.c index fd9399e5..49839a3b 100644 --- a/src/mongoc/mongoc-log.c +++ b/src/mongoc/mongoc-log.c @@ -212,9 +212,9 @@ mongoc_log_default_handler (mongoc_log_level_t log_level, #endif fprintf (stream, - "%s.%04ld: [%5d]: %8s: %12s: %s\n", + "%s.%04" PRId64 ": [%5d]: %8s: %12s: %s\n", nowstr, - tv.tv_usec / 1000L, + (int64_t) (tv.tv_usec / 1000), pid, mongoc_log_level_str (log_level), log_domain, @@ -224,21 +224,20 @@ mongoc_log_default_handler (mongoc_log_level_t log_level, void mongoc_log_trace_bytes (const char *domain, const uint8_t *_b, size_t _l) { - bson_string_t *str, *astr; - int32_t _i; - uint8_t _v; - if (!_mongoc_log_trace_is_enabled ()) { return; } - str = bson_string_new (NULL); - astr = bson_string_new (NULL); - for (_i = 0; _i < _l; _i++) { - _v = *(_b + _i); + bson_string_t *const str = bson_string_new (NULL); + bson_string_t *const astr = bson_string_new (NULL); + + size_t _i; + for (_i = 0u; _i < _l; _i++) { + const uint8_t _v = *(_b + _i); + const size_t rem = _i % 16u; - if ((_i % 16) == 0) { - bson_string_append_printf (str, "%05x: ", _i); + if (rem == 0u) { + bson_string_append_printf (str, "%05zx: ", _i); } bson_string_append_printf (str, " %02x", _v); @@ -248,18 +247,18 @@ mongoc_log_trace_bytes (const char *domain, const uint8_t *_b, size_t _l) bson_string_append (astr, " ."); } - if ((_i % 16) == 15) { + if (rem == 15u) { mongoc_log ( MONGOC_LOG_LEVEL_TRACE, domain, "%s %s", str->str, astr->str); bson_string_truncate (str, 0); bson_string_truncate (astr, 0); - } else if ((_i % 16) == 7) { + } else if (rem == 7u) { bson_string_append (str, " "); bson_string_append (astr, " "); } } - if (_i != 16) { + if (_i != 16u) { mongoc_log ( MONGOC_LOG_LEVEL_TRACE, domain, "%-56s %s", str->str, astr->str); } diff --git a/src/mongoc/mongoc-macros.h b/src/mongoc/mongoc-macros.h index d960c055..a6f48770 100644 --- a/src/mongoc/mongoc-macros.h +++ b/src/mongoc/mongoc-macros.h @@ -20,11 +20,10 @@ #define MONGOC_MACROS_H /* Decorate public functions: - * - if MONGOC_STATIC, we're compiling a program that uses libmongoc as - * a static library, don't decorate functions - * - else if MONGOC_COMPILATION, we're compiling a static or shared libmongoc, - * mark public functions for export from the shared lib (which has no effect - * on the static lib) + * - if MONGOC_STATIC, we're compiling a static libmongoc or a program + * that uses libmongoc as a static library. Don't decorate functions + * - else if MONGOC_COMPILATION, we're compiling a shared libmongoc, + * mark public functions for export from the shared lib. * - else, we're compiling a program that uses libmongoc as a shared library, * mark public functions as DLL imports for Microsoft Visual C. */ diff --git a/src/mongoc/mongoc-matcher-op.c b/src/mongoc/mongoc-matcher-op.c index f5cd160b..a4f63e03 100644 --- a/src/mongoc/mongoc-matcher-op.c +++ b/src/mongoc/mongoc-matcher-op.c @@ -1157,16 +1157,19 @@ _mongoc_matcher_op_to_bson (mongoc_matcher_op_t *op, /* IN */ BSON_ASSERT (false); str = NULL; } - bson_append_array_begin (bson, str, -1, &child); - bson_append_document_begin (&child, "0", 1, &child2); - _mongoc_matcher_op_to_bson (op->logical.left, &child2); - bson_append_document_end (&child, &child2); - if (op->logical.right) { - bson_append_document_begin (&child, "1", 1, &child2); - _mongoc_matcher_op_to_bson (op->logical.right, &child2); - bson_append_document_end (&child, &child2); + { + bson_array_builder_t *bab; + bson_append_array_builder_begin (bson, str, -1, &bab); + bson_array_builder_append_document_begin (bab, &child2); + _mongoc_matcher_op_to_bson (op->logical.left, &child2); + bson_array_builder_append_document_end (bab, &child2); + if (op->logical.right) { + bson_array_builder_append_document_begin (bab, &child2); + _mongoc_matcher_op_to_bson (op->logical.right, &child2); + bson_array_builder_append_document_end (bab, &child2); + } + bson_append_array_builder_end (bson, bab); } - bson_append_array_end (bson, &child); break; case MONGOC_MATCHER_OPCODE_NOT: bson_append_document_begin (bson, op->not_.path, -1, &child); diff --git a/src/mongoc/mongoc-matcher.c b/src/mongoc/mongoc-matcher.c index bf3674a2..fff40144 100644 --- a/src/mongoc/mongoc-matcher.c +++ b/src/mongoc/mongoc-matcher.c @@ -39,7 +39,7 @@ _mongoc_matcher_parse_logical (mongoc_matcher_opcode_t opcode, * * See the following link for more information. * - * http://docs.mongodb.org/manual/reference/operator/query/ + * https://www.mongodb.com/docs/manual/reference/operator/query/ * * Returns: * A newly allocated mongoc_matcher_op_t if successful; otherwise @@ -201,7 +201,7 @@ _mongoc_matcher_parse (bson_iter_t *iter, /* IN */ * * See the following link for more information. * - * http://docs.mongodb.org/manual/reference/operator/query/ + * https://www.mongodb.com/docs/manual/reference/operator/query/ * * Returns: * A newly allocated mongoc_matcher_op_t if successful; otherwise diff --git a/src/mongoc/mongoc-opcode.c b/src/mongoc/mongoc-opcode.c new file mode 100644 index 00000000..0bdcf7ac --- /dev/null +++ b/src/mongoc/mongoc-opcode.c @@ -0,0 +1,35 @@ +/* + * Copyright 2023-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mongoc-opcode.h" + +#include "mcd-rpc.h" + +#include + +// Document and ensure consistency between equivalent macros in mcd-rpc and +// libmongoc. + +BSON_STATIC_ASSERT (MONGOC_OP_CODE_COMPRESSED == MONGOC_OPCODE_COMPRESSED); +BSON_STATIC_ASSERT (MONGOC_OP_CODE_MSG == MONGOC_OPCODE_MSG); + +BSON_STATIC_ASSERT (MONGOC_OP_CODE_REPLY == MONGOC_OPCODE_REPLY); +BSON_STATIC_ASSERT (MONGOC_OP_CODE_UPDATE == MONGOC_OPCODE_UPDATE); +BSON_STATIC_ASSERT (MONGOC_OP_CODE_INSERT == MONGOC_OPCODE_INSERT); +BSON_STATIC_ASSERT (MONGOC_OP_CODE_QUERY == MONGOC_OPCODE_QUERY); +BSON_STATIC_ASSERT (MONGOC_OP_CODE_GET_MORE == MONGOC_OPCODE_GET_MORE); +BSON_STATIC_ASSERT (MONGOC_OP_CODE_DELETE == MONGOC_OPCODE_DELETE); +BSON_STATIC_ASSERT (MONGOC_OP_CODE_KILL_CURSORS == MONGOC_OPCODE_KILL_CURSORS); diff --git a/src/mongoc/mongoc-openssl.c b/src/mongoc/mongoc-openssl.c index 50a73c8d..75708d73 100644 --- a/src/mongoc/mongoc-openssl.c +++ b/src/mongoc/mongoc-openssl.c @@ -76,7 +76,10 @@ _mongoc_openssl_init (void) SSL_library_init (); SSL_load_error_strings (); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + // See: https://www.openssl.org/docs/man3.0/man7/migration_guide.html#Deprecated-function-mappings ERR_load_BIO_strings (); +#endif OpenSSL_add_all_algorithms (); #if OPENSSL_VERSION_NUMBER < 0x10100000L _mongoc_openssl_thread_startup (); diff --git a/src/mongoc/mongoc-opts-helpers.c b/src/mongoc/mongoc-opts-helpers.c index a026e2d3..32bff262 100644 --- a/src/mongoc/mongoc-opts-helpers.c +++ b/src/mongoc/mongoc-opts-helpers.c @@ -63,8 +63,10 @@ _mongoc_timestamp_append (mongoc_timestamp_t *timestamp, bson_t *bson, char *key) { + const size_t len = strlen (key); + BSON_ASSERT (bson_in_range_unsigned (int, len)); bson_append_timestamp ( - bson, key, strlen (key), timestamp->timestamp, timestamp->increment); + bson, key, (int) len, timestamp->timestamp, timestamp->increment); } void diff --git a/src/mongoc/mongoc-opts-private.h b/src/mongoc/mongoc-opts-private.h index 0f9e38dc..6792d077 100644 --- a/src/mongoc/mongoc-opts-private.h +++ b/src/mongoc/mongoc-opts-private.h @@ -146,6 +146,7 @@ typedef struct _mongoc_change_stream_opts_t { int64_t maxAwaitTimeMS; const char *fullDocument; const char *fullDocumentBeforeChange; + bool showExpandedEvents; bson_value_t comment; bson_t extra; } mongoc_change_stream_opts_t; @@ -194,6 +195,7 @@ typedef struct _mongoc_aggregate_opts_t { bool batchSize_is_set; bson_t let; bson_value_t comment; + bson_value_t hint; bson_t extra; } mongoc_aggregate_opts_t; @@ -207,6 +209,18 @@ typedef struct _mongoc_find_and_modify_appended_opts_t { bson_t extra; } mongoc_find_and_modify_appended_opts_t; +typedef struct _mongoc_count_document_opts_t { + bson_t readConcern; + mongoc_client_session_t *client_session; + bson_t collation; + uint32_t serverId; + bson_value_t skip; + bson_value_t limit; + bson_value_t comment; + bson_value_t hint; + bson_t extra; +} mongoc_count_document_opts_t; + bool _mongoc_insert_one_opts_parse ( mongoc_client_t *client, @@ -417,4 +431,14 @@ _mongoc_find_and_modify_appended_opts_parse ( void _mongoc_find_and_modify_appended_opts_cleanup (mongoc_find_and_modify_appended_opts_t *mongoc_find_and_modify_appended_opts); +bool +_mongoc_count_document_opts_parse ( + mongoc_client_t *client, + const bson_t *opts, + mongoc_count_document_opts_t *mongoc_count_document_opts, + bson_error_t *error); + +void +_mongoc_count_document_opts_cleanup (mongoc_count_document_opts_t *mongoc_count_document_opts); + #endif /* MONGOC_OPTS_H */ diff --git a/src/mongoc/mongoc-opts.c b/src/mongoc/mongoc-opts.c index d24d78ae..aa2ad005 100644 --- a/src/mongoc/mongoc-opts.c +++ b/src/mongoc/mongoc-opts.c @@ -23,6 +23,8 @@ _mongoc_insert_one_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_insert_one_opts->crud.writeConcern = NULL; mongoc_insert_one_opts->crud.write_concern_owned = false; mongoc_insert_one_opts->crud.client_session = NULL; @@ -128,6 +130,8 @@ _mongoc_insert_many_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_insert_many_opts->crud.writeConcern = NULL; mongoc_insert_many_opts->crud.write_concern_owned = false; mongoc_insert_many_opts->crud.client_session = NULL; @@ -243,6 +247,8 @@ _mongoc_delete_one_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_delete_one_opts->delete.crud.writeConcern = NULL; mongoc_delete_one_opts->delete.crud.write_concern_owned = false; mongoc_delete_one_opts->delete.crud.client_session = NULL; @@ -371,6 +377,8 @@ _mongoc_delete_many_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_delete_many_opts->delete.crud.writeConcern = NULL; mongoc_delete_many_opts->delete.crud.write_concern_owned = false; mongoc_delete_many_opts->delete.crud.client_session = NULL; @@ -499,6 +507,8 @@ _mongoc_update_one_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_update_one_opts->update.crud.writeConcern = NULL; mongoc_update_one_opts->update.crud.write_concern_owned = false; mongoc_update_one_opts->update.crud.client_session = NULL; @@ -658,6 +668,8 @@ _mongoc_update_many_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_update_many_opts->update.crud.writeConcern = NULL; mongoc_update_many_opts->update.crud.write_concern_owned = false; mongoc_update_many_opts->update.crud.client_session = NULL; @@ -817,6 +829,8 @@ _mongoc_replace_one_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_replace_one_opts->update.crud.writeConcern = NULL; mongoc_replace_one_opts->update.crud.write_concern_owned = false; mongoc_replace_one_opts->update.crud.client_session = NULL; @@ -965,6 +979,8 @@ _mongoc_bulk_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_bulk_opts->writeConcern = NULL; mongoc_bulk_opts->write_concern_owned = false; mongoc_bulk_opts->ordered = true; @@ -1066,6 +1082,8 @@ _mongoc_bulk_insert_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_bulk_insert_opts->validate = _mongoc_default_insert_vflags; bson_init (&mongoc_bulk_insert_opts->extra); @@ -1119,6 +1137,8 @@ _mongoc_bulk_update_one_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_bulk_update_one_opts->update.validate = _mongoc_default_update_vflags; bson_init (&mongoc_bulk_update_one_opts->update.collation); memset (&mongoc_bulk_update_one_opts->update.hint, 0, sizeof (bson_value_t)); @@ -1225,6 +1245,8 @@ _mongoc_bulk_update_many_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_bulk_update_many_opts->update.validate = _mongoc_default_update_vflags; bson_init (&mongoc_bulk_update_many_opts->update.collation); memset (&mongoc_bulk_update_many_opts->update.hint, 0, sizeof (bson_value_t)); @@ -1331,6 +1353,8 @@ _mongoc_bulk_replace_one_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_bulk_replace_one_opts->update.validate = _mongoc_default_replace_vflags; bson_init (&mongoc_bulk_replace_one_opts->update.collation); memset (&mongoc_bulk_replace_one_opts->update.hint, 0, sizeof (bson_value_t)); @@ -1426,6 +1450,8 @@ _mongoc_bulk_remove_one_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + bson_init (&mongoc_bulk_remove_one_opts->remove.collation); memset (&mongoc_bulk_remove_one_opts->remove.hint, 0, sizeof (bson_value_t)); mongoc_bulk_remove_one_opts->remove.limit = 1; @@ -1501,6 +1527,8 @@ _mongoc_bulk_remove_many_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + bson_init (&mongoc_bulk_remove_many_opts->remove.collation); memset (&mongoc_bulk_remove_many_opts->remove.hint, 0, sizeof (bson_value_t)); mongoc_bulk_remove_many_opts->remove.limit = 0; @@ -1576,6 +1604,8 @@ _mongoc_change_stream_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_change_stream_opts->batchSize = 0; bson_init (&mongoc_change_stream_opts->resumeAfter); bson_init (&mongoc_change_stream_opts->startAfter); @@ -1583,6 +1613,7 @@ _mongoc_change_stream_opts_parse ( mongoc_change_stream_opts->maxAwaitTimeMS = 0; mongoc_change_stream_opts->fullDocument = NULL; mongoc_change_stream_opts->fullDocumentBeforeChange = NULL; + mongoc_change_stream_opts->showExpandedEvents = false; memset (&mongoc_change_stream_opts->comment, 0, sizeof (bson_value_t)); bson_init (&mongoc_change_stream_opts->extra); @@ -1662,6 +1693,15 @@ _mongoc_change_stream_opts_parse ( return false; } } + else if (!strcmp (bson_iter_key (&iter), "showExpandedEvents")) { + if (!_mongoc_convert_bool ( + client, + &iter, + &mongoc_change_stream_opts->showExpandedEvents, + error)) { + return false; + } + } else if (!strcmp (bson_iter_key (&iter), "comment")) { if (!_mongoc_convert_bson_value_t ( client, @@ -1707,6 +1747,8 @@ _mongoc_create_index_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_create_index_opts->writeConcern = NULL; mongoc_create_index_opts->write_concern_owned = false; mongoc_create_index_opts->client_session = NULL; @@ -1781,6 +1823,8 @@ _mongoc_read_write_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + bson_init (&mongoc_read_write_opts->readConcern); mongoc_read_write_opts->writeConcern = NULL; mongoc_read_write_opts->write_concern_owned = false; @@ -1887,6 +1931,8 @@ _mongoc_gridfs_bucket_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_gridfs_bucket_opts->bucketName = "fs"; mongoc_gridfs_bucket_opts->chunkSizeBytes = 261120; mongoc_gridfs_bucket_opts->writeConcern = NULL; @@ -1982,6 +2028,8 @@ _mongoc_gridfs_bucket_upload_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_gridfs_bucket_upload_opts->chunkSizeBytes = 0; bson_init (&mongoc_gridfs_bucket_upload_opts->metadata); bson_init (&mongoc_gridfs_bucket_upload_opts->extra); @@ -2051,6 +2099,8 @@ _mongoc_aggregate_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_aggregate_opts->readConcern = NULL; mongoc_aggregate_opts->writeConcern = NULL; mongoc_aggregate_opts->write_concern_owned = false; @@ -2062,6 +2112,7 @@ _mongoc_aggregate_opts_parse ( mongoc_aggregate_opts->batchSize_is_set = false; bson_init (&mongoc_aggregate_opts->let); memset (&mongoc_aggregate_opts->comment, 0, sizeof (bson_value_t)); + memset (&mongoc_aggregate_opts->hint, 0, sizeof (bson_value_t)); bson_init (&mongoc_aggregate_opts->extra); if (!opts) { @@ -2162,6 +2213,15 @@ _mongoc_aggregate_opts_parse ( return false; } } + else if (!strcmp (bson_iter_key (&iter), "hint")) { + if (!_mongoc_convert_hint ( + client, + &iter, + &mongoc_aggregate_opts->hint, + error)) { + return false; + } + } else { /* unrecognized values are copied to "extra" */ if (!BSON_APPEND_VALUE ( @@ -2190,6 +2250,7 @@ _mongoc_aggregate_opts_cleanup (mongoc_aggregate_opts_t *mongoc_aggregate_opts) bson_destroy (&mongoc_aggregate_opts->collation); bson_destroy (&mongoc_aggregate_opts->let); bson_value_destroy (&mongoc_aggregate_opts->comment); + bson_value_destroy (&mongoc_aggregate_opts->hint); bson_destroy (&mongoc_aggregate_opts->extra); } @@ -2202,6 +2263,8 @@ _mongoc_find_and_modify_appended_opts_parse ( { bson_iter_t iter; + BSON_ASSERT (client || true); // client may be NULL. + mongoc_find_and_modify_appended_opts->writeConcern = NULL; mongoc_find_and_modify_appended_opts->write_concern_owned = false; mongoc_find_and_modify_appended_opts->client_session = NULL; @@ -2299,3 +2362,139 @@ _mongoc_find_and_modify_appended_opts_cleanup (mongoc_find_and_modify_appended_o bson_value_destroy (&mongoc_find_and_modify_appended_opts->comment); bson_destroy (&mongoc_find_and_modify_appended_opts->extra); } + +bool +_mongoc_count_document_opts_parse ( + mongoc_client_t *client, + const bson_t *opts, + mongoc_count_document_opts_t *mongoc_count_document_opts, + bson_error_t *error) +{ + bson_iter_t iter; + + BSON_ASSERT (client || true); // client may be NULL. + + bson_init (&mongoc_count_document_opts->readConcern); + mongoc_count_document_opts->client_session = NULL; + bson_init (&mongoc_count_document_opts->collation); + mongoc_count_document_opts->serverId = 0; + memset (&mongoc_count_document_opts->skip, 0, sizeof (bson_value_t)); + memset (&mongoc_count_document_opts->limit, 0, sizeof (bson_value_t)); + memset (&mongoc_count_document_opts->comment, 0, sizeof (bson_value_t)); + memset (&mongoc_count_document_opts->hint, 0, sizeof (bson_value_t)); + bson_init (&mongoc_count_document_opts->extra); + + if (!opts) { + return true; + } + + if (!bson_iter_init (&iter, opts)) { + bson_set_error (error, + MONGOC_ERROR_BSON, + MONGOC_ERROR_BSON_INVALID, + "Invalid 'opts' parameter."); + return false; + } + + while (bson_iter_next (&iter)) { + if (!strcmp (bson_iter_key (&iter), "readConcern")) { + if (!_mongoc_convert_document ( + client, + &iter, + &mongoc_count_document_opts->readConcern, + error)) { + return false; + } + } + else if (!strcmp (bson_iter_key (&iter), "sessionId")) { + if (!_mongoc_convert_session_id ( + client, + &iter, + &mongoc_count_document_opts->client_session, + error)) { + return false; + } + } + else if (!strcmp (bson_iter_key (&iter), "collation")) { + if (!_mongoc_convert_document ( + client, + &iter, + &mongoc_count_document_opts->collation, + error)) { + return false; + } + } + else if (!strcmp (bson_iter_key (&iter), "serverId")) { + if (!_mongoc_convert_server_id ( + client, + &iter, + &mongoc_count_document_opts->serverId, + error)) { + return false; + } + } + else if (!strcmp (bson_iter_key (&iter), "skip")) { + if (!_mongoc_convert_bson_value_t ( + client, + &iter, + &mongoc_count_document_opts->skip, + error)) { + return false; + } + } + else if (!strcmp (bson_iter_key (&iter), "limit")) { + if (!_mongoc_convert_bson_value_t ( + client, + &iter, + &mongoc_count_document_opts->limit, + error)) { + return false; + } + } + else if (!strcmp (bson_iter_key (&iter), "comment")) { + if (!_mongoc_convert_bson_value_t ( + client, + &iter, + &mongoc_count_document_opts->comment, + error)) { + return false; + } + } + else if (!strcmp (bson_iter_key (&iter), "hint")) { + if (!_mongoc_convert_hint ( + client, + &iter, + &mongoc_count_document_opts->hint, + error)) { + return false; + } + } + else { + /* unrecognized values are copied to "extra" */ + if (!BSON_APPEND_VALUE ( + &mongoc_count_document_opts->extra, + bson_iter_key (&iter), + bson_iter_value (&iter))) { + bson_set_error (error, + MONGOC_ERROR_BSON, + MONGOC_ERROR_BSON_INVALID, + "Invalid 'opts' parameter."); + return false; + } + } + } + + return true; +} + +void +_mongoc_count_document_opts_cleanup (mongoc_count_document_opts_t *mongoc_count_document_opts) +{ + bson_destroy (&mongoc_count_document_opts->readConcern); + bson_destroy (&mongoc_count_document_opts->collation); + bson_value_destroy (&mongoc_count_document_opts->skip); + bson_value_destroy (&mongoc_count_document_opts->limit); + bson_value_destroy (&mongoc_count_document_opts->comment); + bson_value_destroy (&mongoc_count_document_opts->hint); + bson_destroy (&mongoc_count_document_opts->extra); +} diff --git a/src/mongoc/mongoc-rand-openssl.c b/src/mongoc/mongoc-rand-openssl.c index ce802876..363bbfbb 100644 --- a/src/mongoc/mongoc-rand-openssl.c +++ b/src/mongoc/mongoc-rand-openssl.c @@ -23,6 +23,7 @@ #include "mongoc.h" +#include #include int diff --git a/src/mongoc/mongoc-read-prefs-private.h b/src/mongoc/mongoc-read-prefs-private.h index 5aae328b..a0d9d787 100644 --- a/src/mongoc/mongoc-read-prefs-private.h +++ b/src/mongoc/mongoc-read-prefs-private.h @@ -38,7 +38,7 @@ struct _mongoc_read_prefs_t { typedef struct _mongoc_assemble_query_result_t { bson_t *assembled_query; bool query_owned; - mongoc_query_flags_t flags; + int32_t flags; } mongoc_assemble_query_result_t; @@ -54,7 +54,7 @@ void assemble_query (const mongoc_read_prefs_t *read_prefs, const mongoc_server_stream_t *server_stream, const bson_t *query_bson, - mongoc_query_flags_t initial_flags, + int32_t initial_flags, mongoc_assemble_query_result_t *result); void diff --git a/src/mongoc/mongoc-read-prefs.c b/src/mongoc/mongoc-read-prefs.c index 6b9483a2..525f26b8 100644 --- a/src/mongoc/mongoc-read-prefs.c +++ b/src/mongoc/mongoc-read-prefs.c @@ -332,7 +332,7 @@ void assemble_query (const mongoc_read_prefs_t *read_prefs, const mongoc_server_stream_t *server_stream, const bson_t *query_bson, - mongoc_query_flags_t initial_flags, + int32_t initial_flags, mongoc_assemble_query_result_t *result /* OUT */) { mongoc_server_description_type_t server_type; @@ -360,7 +360,7 @@ assemble_query (const mongoc_read_prefs_t *read_prefs, * protocol flag on reads to ensure that any server type can handle the * request." */ - result->flags |= MONGOC_QUERY_SECONDARY_OK; + result->flags |= MONGOC_OP_QUERY_FLAG_SECONDARY_OK; } break; @@ -374,7 +374,7 @@ assemble_query (const mongoc_read_prefs_t *read_prefs, * the read preference mode is primary. */ if (read_prefs && read_prefs->mode != MONGOC_READ_PRIMARY) { - result->flags |= MONGOC_QUERY_SECONDARY_OK; + result->flags |= MONGOC_OP_QUERY_FLAG_SECONDARY_OK; } break; diff --git a/src/mongoc/mongoc-rpc-private.h b/src/mongoc/mongoc-rpc-private.h index 794ad87b..79b3f9bc 100644 --- a/src/mongoc/mongoc-rpc-private.h +++ b/src/mongoc/mongoc-rpc-private.h @@ -14,153 +14,28 @@ * limitations under the License. */ -#include "mongoc-prelude.h" - #ifndef MONGOC_RPC_PRIVATE_H #define MONGOC_RPC_PRIVATE_H -#include -#include - -#include "mongoc-array-private.h" -#include "mongoc-cmd-private.h" -#include "mongoc-iovec.h" -#include "mongoc-write-concern.h" -#include "mongoc-flags.h" -/* forward declaration */ -struct _mongoc_cluster_t; - -BSON_BEGIN_DECLS - -typedef struct _mongoc_rpc_section_t { - uint8_t payload_type; - union { - /* payload_type == 0 */ - const uint8_t *bson_document; - /* payload_type == 1 */ - struct { - int32_t size; - uint32_t size_le; - const char *identifier; - const uint8_t *bson_documents; - } sequence; - } payload; -} mongoc_rpc_section_t; - -#define RPC(_name, _code) \ - typedef struct { \ - _code \ - } mongoc_rpc_##_name##_t; -#define ENUM_FIELD(_name) uint32_t _name; -#define INT32_FIELD(_name) int32_t _name; -#define UINT8_FIELD(_name) uint8_t _name; -#define INT64_FIELD(_name) int64_t _name; -#define INT64_ARRAY_FIELD(_len, _name) \ - int32_t _len; \ - int64_t *_name; -#define CSTRING_FIELD(_name) const char *_name; -#define BSON_FIELD(_name) const uint8_t *_name; -#define BSON_ARRAY_FIELD(_name) \ - const uint8_t *_name; \ - int32_t _name##_len; -#define IOVEC_ARRAY_FIELD(_name) \ - const mongoc_iovec_t *_name; \ - int32_t n_##_name; \ - mongoc_iovec_t _name##_recv; -#define SECTION_ARRAY_FIELD(_name) \ - mongoc_rpc_section_t _name[2]; \ - int32_t n_##_name; -#define RAW_BUFFER_FIELD(_name) \ - const uint8_t *_name; \ - int32_t _name##_len; -#define BSON_OPTIONAL(_check, _code) _code - - -#pragma pack(1) -#include "op-delete.def" -#include "op-get-more.def" -#include "op-header.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-reply-header.def" -#include "op-update.def" -#include "op-compressed.def" -/* restore default packing */ -#pragma pack() - -#include "op-msg.def" - -typedef union { - mongoc_rpc_delete_t delete_; - mongoc_rpc_get_more_t get_more; - mongoc_rpc_header_t header; - mongoc_rpc_insert_t insert; - mongoc_rpc_kill_cursors_t kill_cursors; - mongoc_rpc_msg_t msg; - mongoc_rpc_query_t query; - mongoc_rpc_reply_t reply; - mongoc_rpc_reply_header_t reply_header; - mongoc_rpc_update_t update; - mongoc_rpc_compressed_t compressed; -} mongoc_rpc_t; - - -BSON_STATIC_ASSERT2 (sizeof_rpc_header, sizeof (mongoc_rpc_header_t) == 16); -BSON_STATIC_ASSERT2 (offsetof_rpc_header, - offsetof (mongoc_rpc_header_t, opcode) == - offsetof (mongoc_rpc_reply_t, opcode)); -BSON_STATIC_ASSERT2 (sizeof_reply_header, - sizeof (mongoc_rpc_reply_header_t) == 36); +#include "mongoc-prelude.h" +#include "mcd-rpc.h" -#undef RPC -#undef ENUM_FIELD -#undef UINT8_FIELD -#undef INT32_FIELD -#undef INT64_FIELD -#undef INT64_ARRAY_FIELD -#undef CSTRING_FIELD -#undef BSON_FIELD -#undef BSON_ARRAY_FIELD -#undef IOVEC_ARRAY_FIELD -#undef SECTION_ARRAY_FIELD -#undef BSON_OPTIONAL -#undef RAW_BUFFER_FIELD +#include +#include +#include -void -_mongoc_rpc_gather (mongoc_rpc_t *rpc, mongoc_array_t *array); -void -_mongoc_rpc_swab_to_le (mongoc_rpc_t *rpc); -void -_mongoc_rpc_swab_from_le (mongoc_rpc_t *rpc); -void -_mongoc_rpc_printf (mongoc_rpc_t *rpc); -bool -_mongoc_rpc_scatter (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen); -bool -_mongoc_rpc_scatter_reply_header_only (mongoc_rpc_t *rpc, - const uint8_t *buf, - size_t buflen); +BSON_BEGIN_DECLS bool -_mongoc_rpc_get_first_document (mongoc_rpc_t *rpc, bson_t *reply); -bool -_mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson); -bool -_mongoc_rpc_reply_get_first_msg (mongoc_rpc_msg_t *reply, bson_t *bson); +mcd_rpc_message_get_body (const mcd_rpc_message *rpc, bson_t *reply); -void -_mongoc_rpc_prep_command (mongoc_rpc_t *rpc, - const char *cmd_ns, - mongoc_cmd_t *cmd); bool -_mongoc_rpc_check_ok (mongoc_rpc_t *rpc, - int32_t error_api_version, - bson_error_t *error /* OUT */, - bson_t *error_doc /* OUT */); +mcd_rpc_message_check_ok (mcd_rpc_message *rpc, + int32_t error_api_version, + bson_error_t *error /* OUT */, + bson_t *error_doc /* OUT */); bool _mongoc_cmd_check_ok (const bson_t *doc, int32_t error_api_version, @@ -171,19 +46,10 @@ _mongoc_cmd_check_ok_no_wce (const bson_t *doc, int32_t error_api_version, bson_error_t *error); -bool -_mongoc_rpc_decompress (mongoc_rpc_t *rpc_le, uint8_t *buf, size_t buflen); - -char * -_mongoc_rpc_compress (struct _mongoc_cluster_t *cluster, - int32_t compressor_id, - mongoc_rpc_t *rpc_le, - bson_error_t *error); - -bool -_mongoc_rpc_decompress_if_necessary (mongoc_rpc_t *rpc, - mongoc_buffer_t *buffer, - bson_error_t *error); +void +mcd_rpc_message_egress (const mcd_rpc_message *rpc); +void +mcd_rpc_message_ingress (const mcd_rpc_message *rpc); BSON_END_DECLS diff --git a/src/mongoc/mongoc-rpc.c b/src/mongoc/mongoc-rpc.c index a5750b39..61edc446 100644 --- a/src/mongoc/mongoc-rpc.c +++ b/src/mongoc/mongoc-rpc.c @@ -15,1077 +15,64 @@ */ -#include - -#include "mongoc.h" #include "mongoc-rpc-private.h" + #include "mongoc-counters-private.h" #include "mongoc-trace-private.h" -#include "mongoc-util-private.h" -#include "mongoc-compression-private.h" -#include "mongoc-cluster-private.h" - - -#define RPC(_name, _code) \ - static void _mongoc_rpc_gather_##_name (mongoc_rpc_##_name##_t *rpc, \ - mongoc_rpc_header_t *header, \ - mongoc_array_t *array) \ - { \ - mongoc_iovec_t iov; \ - BSON_ASSERT (rpc); \ - BSON_ASSERT (array); \ - header->msg_len = 0; \ - _code \ - } -#define UINT8_FIELD(_name) \ - iov.iov_base = (void *) &rpc->_name; \ - iov.iov_len = 1; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); -#define INT32_FIELD(_name) \ - iov.iov_base = (void *) &rpc->_name; \ - iov.iov_len = 4; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); -#define ENUM_FIELD INT32_FIELD -#define INT64_FIELD(_name) \ - iov.iov_base = (void *) &rpc->_name; \ - iov.iov_len = 8; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); -#define CSTRING_FIELD(_name) \ - BSON_ASSERT (rpc->_name); \ - iov.iov_base = (void *) rpc->_name; \ - iov.iov_len = strlen (rpc->_name) + 1; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); -#define BSON_FIELD(_name) \ - do { \ - int32_t __l; \ - memcpy (&__l, rpc->_name, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - iov.iov_base = (void *) rpc->_name; \ - iov.iov_len = __l; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - } while (0); -#define BSON_OPTIONAL(_check, _code) \ - if (rpc->_check) { \ - _code \ - } -#define BSON_ARRAY_FIELD(_name) \ - if (rpc->_name##_len) { \ - iov.iov_base = (void *) rpc->_name; \ - iov.iov_len = rpc->_name##_len; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - } -#define IOVEC_ARRAY_FIELD(_name) \ - do { \ - ssize_t _i; \ - BSON_ASSERT (rpc->n_##_name); \ - for (_i = 0; _i < rpc->n_##_name; _i++) { \ - BSON_ASSERT (rpc->_name[_i].iov_len); \ - header->msg_len += (int32_t) rpc->_name[_i].iov_len; \ - _mongoc_array_append_val (array, rpc->_name[_i]); \ - } \ - } while (0); -#define SECTION_ARRAY_FIELD(_name) \ - do { \ - ssize_t _i; \ - BSON_ASSERT (rpc->n_##_name); \ - for (_i = 0; _i < rpc->n_##_name; _i++) { \ - int32_t __l; \ - iov.iov_base = (void *) &rpc->_name[_i].payload_type; \ - iov.iov_len = 1; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - switch (rpc->_name[_i].payload_type) { \ - case 0: \ - memcpy (&__l, rpc->_name[_i].payload.bson_document, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - iov.iov_base = (void *) rpc->_name[_i].payload.bson_document; \ - iov.iov_len = __l; \ - break; \ - case 1: \ - rpc->_name[_i].payload.sequence.size_le = \ - BSON_UINT32_TO_LE (rpc->_name[_i].payload.sequence.size); \ - iov.iov_base = (void *) &rpc->_name[_i].payload.sequence.size_le; \ - iov.iov_len = 4; \ - header->msg_len += 4; \ - _mongoc_array_append_val (array, iov); \ - iov.iov_base = \ - (void *) rpc->_name[_i].payload.sequence.identifier; \ - iov.iov_len = \ - strlen (rpc->_name[_i].payload.sequence.identifier) + 1; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - iov.iov_base = \ - (void *) rpc->_name[_i].payload.sequence.bson_documents; \ - iov.iov_len = \ - rpc->_name[_i].payload.sequence.size - iov.iov_len - 4; \ - break; \ - default: \ - MONGOC_ERROR ("Unknown Payload Type: %d", \ - rpc->_name[_i].payload_type); \ - BSON_ASSERT (0); \ - } \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - } \ - } while (0); -#define RAW_BUFFER_FIELD(_name) \ - iov.iov_base = (void *) rpc->_name; \ - iov.iov_len = rpc->_name##_len; \ - BSON_ASSERT (iov.iov_len); \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); -#define INT64_ARRAY_FIELD(_len, _name) \ - iov.iov_base = (void *) &rpc->_len; \ - iov.iov_len = 4; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - iov.iov_base = (void *) rpc->_name; \ - iov.iov_len = rpc->_len * 8; \ - BSON_ASSERT (iov.iov_len); \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); - - -#include "op-delete.def" -#include "op-get-more.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-msg.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-compressed.def" -#include "op-update.def" - - -#undef RPC -#undef ENUM_FIELD -#undef UINT8_FIELD -#undef INT32_FIELD -#undef INT64_FIELD -#undef INT64_ARRAY_FIELD -#undef CSTRING_FIELD -#undef BSON_FIELD -#undef BSON_ARRAY_FIELD -#undef IOVEC_ARRAY_FIELD -#undef SECTION_ARRAY_FIELD -#undef RAW_BUFFER_FIELD -#undef BSON_OPTIONAL - - -#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN - -#define RPC(_name, _code) \ - static void _mongoc_rpc_swab_to_le_##_name (mongoc_rpc_##_name##_t *rpc) \ - { \ - BSON_ASSERT (rpc); \ - _code \ - } -#define UINT8_FIELD(_name) -#define INT32_FIELD(_name) rpc->_name = BSON_UINT32_FROM_LE (rpc->_name); -#define ENUM_FIELD INT32_FIELD -#define INT64_FIELD(_name) rpc->_name = BSON_UINT64_FROM_LE (rpc->_name); -#define CSTRING_FIELD(_name) -#define BSON_FIELD(_name) -#define BSON_ARRAY_FIELD(_name) -#define IOVEC_ARRAY_FIELD(_name) -#define SECTION_ARRAY_FIELD(_name) -#define BSON_OPTIONAL(_check, _code) \ - if (rpc->_check) { \ - _code \ - } -#define RAW_BUFFER_FIELD(_name) -#define INT64_ARRAY_FIELD(_len, _name) \ - do { \ - ssize_t i; \ - for (i = 0; i < rpc->_len; i++) { \ - rpc->_name[i] = BSON_UINT64_FROM_LE (rpc->_name[i]); \ - } \ - rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \ - } while (0); - - -#include "op-delete.def" -#include "op-get-more.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-msg.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-compressed.def" -#include "op-update.def" - -#undef RPC -#undef INT64_ARRAY_FIELD - -#define RPC(_name, _code) \ - static void _mongoc_rpc_swab_from_le_##_name (mongoc_rpc_##_name##_t *rpc) \ - { \ - BSON_ASSERT (rpc); \ - _code \ - } -#define INT64_ARRAY_FIELD(_len, _name) \ - do { \ - ssize_t i; \ - rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \ - for (i = 0; i < rpc->_len; i++) { \ - rpc->_name[i] = BSON_UINT64_FROM_LE (rpc->_name[i]); \ - } \ - } while (0); - - -#include "op-delete.def" -#include "op-get-more.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-msg.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-compressed.def" -#include "op-update.def" - -#undef RPC -#undef ENUM_FIELD -#undef UINT8_FIELD -#undef INT32_FIELD -#undef INT64_FIELD -#undef INT64_ARRAY_FIELD -#undef CSTRING_FIELD -#undef BSON_FIELD -#undef BSON_ARRAY_FIELD -#undef IOVEC_ARRAY_FIELD -#undef SECTION_ARRAY_FIELD -#undef BSON_OPTIONAL -#undef RAW_BUFFER_FIELD - -#endif /* BSON_BYTE_ORDER == BSON_BIG_ENDIAN */ - - -#define RPC(_name, _code) \ - static void _mongoc_rpc_printf_##_name (mongoc_rpc_##_name##_t *rpc) \ - { \ - BSON_ASSERT (rpc); \ - _code \ - } -#define UINT8_FIELD(_name) printf (" " #_name " : %u\n", rpc->_name); -#define INT32_FIELD(_name) printf (" " #_name " : %d\n", rpc->_name); -#define ENUM_FIELD(_name) printf (" " #_name " : %u\n", rpc->_name); -#define INT64_FIELD(_name) \ - printf (" " #_name " : %" PRIi64 "\n", (int64_t) rpc->_name); -#define CSTRING_FIELD(_name) printf (" " #_name " : %s\n", rpc->_name); -#define BSON_FIELD(_name) \ - do { \ - bson_t b; \ - char *s; \ - int32_t __l; \ - memcpy (&__l, rpc->_name, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - BSON_ASSERT (bson_init_static (&b, rpc->_name, __l)); \ - s = bson_as_relaxed_extended_json (&b, NULL); \ - printf (" " #_name " : %s\n", s); \ - bson_free (s); \ - bson_destroy (&b); \ - } while (0); -#define BSON_ARRAY_FIELD(_name) \ - do { \ - bson_reader_t *__r; \ - bool __eof; \ - const bson_t *__b; \ - __r = bson_reader_new_from_data (rpc->_name, rpc->_name##_len); \ - while ((__b = bson_reader_read (__r, &__eof))) { \ - char *s = bson_as_relaxed_extended_json (__b, NULL); \ - printf (" " #_name " : %s\n", s); \ - bson_free (s); \ - } \ - bson_reader_destroy (__r); \ - } while (0); -#define IOVEC_ARRAY_FIELD(_name) \ - do { \ - ssize_t _i; \ - size_t _j; \ - for (_i = 0; _i < rpc->n_##_name; _i++) { \ - printf (" " #_name " : "); \ - for (_j = 0; _j < rpc->_name[_i].iov_len; _j++) { \ - uint8_t u; \ - u = ((char *) rpc->_name[_i].iov_base)[_j]; \ - printf (" %02x", u); \ - } \ - printf ("\n"); \ - } \ - } while (0); -#define SECTION_ARRAY_FIELD(_name) \ - do { \ - ssize_t _i; \ - printf (" " #_name " : %d\n", rpc->n_##_name); \ - for (_i = 0; _i < rpc->n_##_name; _i++) { \ - if (rpc->_name[_i].payload_type == 0) { \ - do { \ - bson_t b; \ - char *s; \ - int32_t __l; \ - memcpy (&__l, rpc->_name[_i].payload.bson_document, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - BSON_ASSERT (bson_init_static ( \ - &b, rpc->_name[_i].payload.bson_document, __l)); \ - s = bson_as_relaxed_extended_json (&b, NULL); \ - printf (" Type %d: %s\n", rpc->_name[_i].payload_type, s); \ - bson_free (s); \ - bson_destroy (&b); \ - } while (0); \ - } else if (rpc->_name[_i].payload_type == 1) { \ - bson_reader_t *__r; \ - int max = rpc->_name[_i].payload.sequence.size - \ - strlen (rpc->_name[_i].payload.sequence.identifier) - \ - 1 - sizeof (int32_t); \ - bool __eof; \ - const bson_t *__b; \ - printf (" Identifier: %s\n", \ - rpc->_name[_i].payload.sequence.identifier); \ - printf (" Size: %d\n", max); \ - __r = bson_reader_new_from_data ( \ - rpc->_name[_i].payload.sequence.bson_documents, max); \ - while ((__b = bson_reader_read (__r, &__eof))) { \ - char *s = bson_as_relaxed_extended_json (__b, NULL); \ - bson_free (s); \ - } \ - bson_reader_destroy (__r); \ - } \ - } \ - } while (0); -#define BSON_OPTIONAL(_check, _code) \ - if (rpc->_check) { \ - _code \ - } -#define RAW_BUFFER_FIELD(_name) \ - { \ - ssize_t __i; \ - printf (" " #_name " :"); \ - for (__i = 0; __i < rpc->_name##_len; __i++) { \ - uint8_t u; \ - u = ((char *) rpc->_name)[__i]; \ - printf (" %02x", u); \ - } \ - printf ("\n"); \ - } -#define INT64_ARRAY_FIELD(_len, _name) \ - do { \ - ssize_t i; \ - for (i = 0; i < rpc->_len; i++) { \ - printf (" " #_name " : %" PRIi64 "\n", (int64_t) rpc->_name[i]); \ - } \ - rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \ - } while (0); - - -#include "op-delete.def" -#include "op-get-more.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-msg.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-compressed.def" -#include "op-update.def" - - -#undef RPC -#undef ENUM_FIELD -#undef UINT8_FIELD -#undef INT32_FIELD -#undef INT64_FIELD -#undef INT64_ARRAY_FIELD -#undef CSTRING_FIELD -#undef BSON_FIELD -#undef BSON_ARRAY_FIELD -#undef IOVEC_ARRAY_FIELD -#undef SECTION_ARRAY_FIELD -#undef BSON_OPTIONAL -#undef RAW_BUFFER_FIELD - - -#define RPC(_name, _code) \ - static bool _mongoc_rpc_scatter_##_name ( \ - mongoc_rpc_##_name##_t *rpc, const uint8_t *buf, size_t buflen) \ - { \ - BSON_ASSERT (rpc); \ - BSON_ASSERT (buf); \ - BSON_ASSERT (buflen); \ - _code return true; \ - } -#define UINT8_FIELD(_name) \ - if (buflen < 1) { \ - return false; \ - } \ - memcpy (&rpc->_name, buf, 1); \ - buflen -= 1; \ - buf += 1; -#define INT32_FIELD(_name) \ - if (buflen < 4) { \ - return false; \ - } \ - memcpy (&rpc->_name, buf, 4); \ - buflen -= 4; \ - buf += 4; -#define ENUM_FIELD INT32_FIELD -#define INT64_FIELD(_name) \ - if (buflen < 8) { \ - return false; \ - } \ - memcpy (&rpc->_name, buf, 8); \ - buflen -= 8; \ - buf += 8; -#define INT64_ARRAY_FIELD(_len, _name) \ - do { \ - size_t needed; \ - if (buflen < 4) { \ - return false; \ - } \ - memcpy (&rpc->_len, buf, 4); \ - buflen -= 4; \ - buf += 4; \ - needed = BSON_UINT32_FROM_LE (rpc->_len) * 8; \ - if (needed > buflen) { \ - return false; \ - } \ - rpc->_name = (int64_t *) buf; \ - buf += needed; \ - buflen -= needed; \ - } while (0); -#define CSTRING_FIELD(_name) \ - do { \ - size_t __i; \ - bool found = false; \ - for (__i = 0; __i < buflen; __i++) { \ - if (!buf[__i]) { \ - rpc->_name = (const char *) buf; \ - buflen -= __i + 1; \ - buf += __i + 1; \ - found = true; \ - break; \ - } \ - } \ - if (!found) { \ - return false; \ - } \ - } while (0); -#define BSON_FIELD(_name) \ - do { \ - uint32_t __l; \ - if (buflen < 4) { \ - return false; \ - } \ - memcpy (&__l, buf, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - if (__l < 5 || __l > buflen) { \ - return false; \ - } \ - rpc->_name = (uint8_t *) buf; \ - buf += __l; \ - buflen -= __l; \ - } while (0); -#define BSON_ARRAY_FIELD(_name) \ - rpc->_name = (uint8_t *) buf; \ - rpc->_name##_len = (int32_t) buflen; \ - buf = NULL; \ - buflen = 0; -#define BSON_OPTIONAL(_check, _code) \ - if (buflen) { \ - _code \ - } -#define IOVEC_ARRAY_FIELD(_name) \ - rpc->_name##_recv.iov_base = (void *) buf; \ - rpc->_name##_recv.iov_len = buflen; \ - rpc->_name = &rpc->_name##_recv; \ - rpc->n_##_name = 1; \ - buf = NULL; \ - buflen = 0; -#define SECTION_ARRAY_FIELD(_name) \ - do { \ - uint32_t __l; \ - mongoc_rpc_section_t *section = &rpc->_name[rpc->n_##_name]; \ - section->payload_type = buf[0]; \ - buf++; \ - buflen -= 1; \ - memcpy (&__l, buf, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - if (section->payload_type == 0) { \ - section->payload.bson_document = buf; \ - } else { \ - const uint8_t *section_buf = buf + 4; \ - section->payload.sequence.size = __l; \ - section->payload.sequence.identifier = (const char *) section_buf; \ - section_buf += strlen ((const char *) section_buf) + 1; \ - section->payload.sequence.bson_documents = section_buf; \ - } \ - buf += __l; \ - buflen -= __l; \ - rpc->n_##_name++; \ - } while (buflen); -#define RAW_BUFFER_FIELD(_name) \ - rpc->_name = (void *) buf; \ - rpc->_name##_len = (int32_t) buflen; \ - buf = NULL; \ - buflen = 0; - - -#include "op-delete.def" -#include "op-get-more.def" -#include "op-header.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-msg.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-reply-header.def" -#include "op-compressed.def" -#include "op-update.def" - - -#undef RPC -#undef ENUM_FIELD -#undef UINT8_FIELD -#undef INT32_FIELD -#undef INT64_FIELD -#undef INT64_ARRAY_FIELD -#undef CSTRING_FIELD -#undef BSON_FIELD -#undef BSON_ARRAY_FIELD -#undef IOVEC_ARRAY_FIELD -#undef SECTION_ARRAY_FIELD -#undef BSON_OPTIONAL -#undef RAW_BUFFER_FIELD -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_gather -- - * - * Takes a (native endian) rpc struct and gathers the buffer. - * Caller should swab to little endian after calling gather. - * - * Gather, swab, compress write. - * Read, scatter, uncompress, swab - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_rpc_gather (mongoc_rpc_t *rpc, mongoc_array_t *array) +bool +mcd_rpc_message_get_body (const mcd_rpc_message *rpc, bson_t *reply) { - mongoc_counter_op_egress_total_inc (); - switch ((mongoc_opcode_t) rpc->header.opcode) { - case MONGOC_OPCODE_REPLY: - _mongoc_rpc_gather_reply (&rpc->reply, &rpc->header, array); - return; - - case MONGOC_OPCODE_MSG: - _mongoc_rpc_gather_msg (&rpc->msg, &rpc->header, array); - mongoc_counter_op_egress_msg_inc (); - return; + switch (mcd_rpc_header_get_op_code (rpc)) { + case MONGOC_OP_CODE_MSG: { + const size_t sections_count = mcd_rpc_op_msg_get_sections_count (rpc); - case MONGOC_OPCODE_UPDATE: - _mongoc_rpc_gather_update (&rpc->update, &rpc->header, array); - mongoc_counter_op_egress_update_inc (); - return; + // Look for section kind 0. + for (size_t index = 0u; index < sections_count; ++index) { + switch (mcd_rpc_op_msg_section_get_kind (rpc, index)) { + case 0: { // Body. + const uint8_t *const body = + mcd_rpc_op_msg_section_get_body (rpc, index); - case MONGOC_OPCODE_INSERT: - _mongoc_rpc_gather_insert (&rpc->insert, &rpc->header, array); - mongoc_counter_op_egress_insert_inc (); - return; - - case MONGOC_OPCODE_QUERY: - _mongoc_rpc_gather_query (&rpc->query, &rpc->header, array); - mongoc_counter_op_egress_query_inc (); - return; - - case MONGOC_OPCODE_GET_MORE: - _mongoc_rpc_gather_get_more (&rpc->get_more, &rpc->header, array); - mongoc_counter_op_egress_getmore_inc (); - return; - - case MONGOC_OPCODE_DELETE: - _mongoc_rpc_gather_delete (&rpc->delete_, &rpc->header, array); - mongoc_counter_op_egress_delete_inc (); - return; + const int32_t body_len = + bson_iter_int32_unsafe (&(bson_iter_t){.raw = body}); - case MONGOC_OPCODE_KILL_CURSORS: - _mongoc_rpc_gather_kill_cursors (&rpc->kill_cursors, &rpc->header, array); - mongoc_counter_op_egress_killcursors_inc (); - return; + return bson_init_static (reply, body, (size_t) body_len); + } - case MONGOC_OPCODE_COMPRESSED: - _mongoc_rpc_gather_compressed (&rpc->compressed, &rpc->header, array); - mongoc_counter_op_egress_compressed_inc (); - return; + case 1: // Document Sequence. + continue; - default: - MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode); - BSON_ASSERT (false); + default: + // Validated by `mcd_rpc_message_from_data`. + BSON_UNREACHABLE ("invalid OP_MSG section kind"); + } + } break; } -} - -void -_mongoc_rpc_swab_to_le (mongoc_rpc_t *rpc) -{ - BSON_UNUSED (rpc); - -#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN - { - mongoc_opcode_t opcode; - - opcode = rpc->header.opcode; - - switch (opcode) { - case MONGOC_OPCODE_REPLY: - _mongoc_rpc_swab_to_le_reply (&rpc->reply); - break; - case MONGOC_OPCODE_MSG: - _mongoc_rpc_swab_to_le_msg (&rpc->msg); - break; - case MONGOC_OPCODE_UPDATE: - _mongoc_rpc_swab_to_le_update (&rpc->update); - break; - case MONGOC_OPCODE_INSERT: - _mongoc_rpc_swab_to_le_insert (&rpc->insert); - break; - case MONGOC_OPCODE_QUERY: - _mongoc_rpc_swab_to_le_query (&rpc->query); - break; - case MONGOC_OPCODE_GET_MORE: - _mongoc_rpc_swab_to_le_get_more (&rpc->get_more); - break; - case MONGOC_OPCODE_DELETE: - _mongoc_rpc_swab_to_le_delete (&rpc->delete_); - break; - case MONGOC_OPCODE_KILL_CURSORS: - _mongoc_rpc_swab_to_le_kill_cursors (&rpc->kill_cursors); - break; - case MONGOC_OPCODE_COMPRESSED: - _mongoc_rpc_swab_to_le_compressed (&rpc->compressed); - break; - default: - MONGOC_WARNING ("Unknown rpc type: 0x%08x", opcode); - break; + case MONGOC_OP_CODE_REPLY: { + if (mcd_rpc_op_reply_get_documents_len (rpc) < 1) { + return false; } - } -#endif -#if 0 - _mongoc_rpc_printf (rpc); -#endif -} + // Assume the first document in OP_REPLY is the body. + const uint8_t *const body = mcd_rpc_op_reply_get_documents (rpc); -void -_mongoc_rpc_swab_from_le (mongoc_rpc_t *rpc) -{ - BSON_UNUSED (rpc); - -#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN - { - mongoc_opcode_t opcode; - - opcode = BSON_UINT32_FROM_LE (rpc->header.opcode); - - switch (opcode) { - case MONGOC_OPCODE_REPLY: - _mongoc_rpc_swab_from_le_reply (&rpc->reply); - break; - case MONGOC_OPCODE_MSG: - _mongoc_rpc_swab_from_le_msg (&rpc->msg); - break; - case MONGOC_OPCODE_UPDATE: - _mongoc_rpc_swab_from_le_update (&rpc->update); - break; - case MONGOC_OPCODE_INSERT: - _mongoc_rpc_swab_from_le_insert (&rpc->insert); - break; - case MONGOC_OPCODE_QUERY: - _mongoc_rpc_swab_from_le_query (&rpc->query); - break; - case MONGOC_OPCODE_GET_MORE: - _mongoc_rpc_swab_from_le_get_more (&rpc->get_more); - break; - case MONGOC_OPCODE_DELETE: - _mongoc_rpc_swab_from_le_delete (&rpc->delete_); - break; - case MONGOC_OPCODE_KILL_CURSORS: - _mongoc_rpc_swab_from_le_kill_cursors (&rpc->kill_cursors); - break; - case MONGOC_OPCODE_COMPRESSED: - _mongoc_rpc_swab_from_le_compressed (&rpc->compressed); - break; - default: - MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode); - break; - } + return bson_init_static ( + reply, + body, + (size_t) bson_iter_int32_unsafe (&(bson_iter_t){.raw = body})); } -#endif -#if 0 - _mongoc_rpc_printf (rpc); -#endif -} - -void -_mongoc_rpc_printf (mongoc_rpc_t *rpc) -{ - switch ((mongoc_opcode_t) rpc->header.opcode) { - case MONGOC_OPCODE_REPLY: - _mongoc_rpc_printf_reply (&rpc->reply); - break; - case MONGOC_OPCODE_MSG: - _mongoc_rpc_printf_msg (&rpc->msg); - break; - case MONGOC_OPCODE_UPDATE: - _mongoc_rpc_printf_update (&rpc->update); - break; - case MONGOC_OPCODE_INSERT: - _mongoc_rpc_printf_insert (&rpc->insert); - break; - case MONGOC_OPCODE_QUERY: - _mongoc_rpc_printf_query (&rpc->query); - break; - case MONGOC_OPCODE_GET_MORE: - _mongoc_rpc_printf_get_more (&rpc->get_more); - break; - case MONGOC_OPCODE_DELETE: - _mongoc_rpc_printf_delete (&rpc->delete_); - break; - case MONGOC_OPCODE_KILL_CURSORS: - _mongoc_rpc_printf_kill_cursors (&rpc->kill_cursors); - break; - case MONGOC_OPCODE_COMPRESSED: - _mongoc_rpc_printf_compressed (&rpc->compressed); - break; default: - MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode); break; } - printf ("\n"); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_decompress -- - * - * Takes a (little endian) rpc struct assumed to be OP_COMPRESSED - * and decompresses the opcode into its original opcode. - * The in-place updated rpc struct remains little endian. - * - * Side effects: - * Overwrites the RPC, along with the provided buf with the - * compressed results. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_rpc_decompress (mongoc_rpc_t *rpc_le, uint8_t *buf, size_t buflen) -{ - size_t uncompressed_size = - BSON_UINT32_FROM_LE (rpc_le->compressed.uncompressed_size); - bool ok; - size_t msg_len = BSON_UINT32_TO_LE (buflen); - const size_t original_uncompressed_size = uncompressed_size; - - BSON_ASSERT (uncompressed_size <= buflen); - memcpy (buf, (void *) (&msg_len), 4); - memcpy (buf + 4, (void *) (&rpc_le->header.request_id), 4); - memcpy (buf + 8, (void *) (&rpc_le->header.response_to), 4); - memcpy (buf + 12, (void *) (&rpc_le->compressed.original_opcode), 4); - - ok = mongoc_uncompress (rpc_le->compressed.compressor_id, - rpc_le->compressed.compressed_message, - rpc_le->compressed.compressed_message_len, - buf + 16, - &uncompressed_size); - - BSON_ASSERT (original_uncompressed_size == uncompressed_size); - - if (ok) { - return _mongoc_rpc_scatter (rpc_le, buf, buflen); - } return false; } -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_compress -- - * - * Takes a (little endian) rpc struct and creates a OP_COMPRESSED - * compressed opcode based on the provided compressor_id. - * The in-place updated rpc struct remains little endian. - * - * Side effects: - * Overwrites the RPC, and clears and overwrites the cluster buffer - * with the compressed results. - * - *-------------------------------------------------------------------------- - */ - -char * -_mongoc_rpc_compress (struct _mongoc_cluster_t *cluster, - int32_t compressor_id, - mongoc_rpc_t *rpc_le, - bson_error_t *error) -{ - char *output; - size_t output_length = 0; - size_t allocate = BSON_UINT32_FROM_LE (rpc_le->header.msg_len) - 16; - char *data; - int size; - int32_t compression_level = -1; - - if (compressor_id == MONGOC_COMPRESSOR_ZLIB_ID) { - compression_level = mongoc_uri_get_option_as_int32 ( - cluster->uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, -1); - } - - BSON_ASSERT (allocate > 0); - data = bson_malloc0 (allocate); - size = _mongoc_cluster_buffer_iovec ( - cluster->iov.data, cluster->iov.len, 16, data); - BSON_ASSERT (size); - - output_length = - mongoc_compressor_max_compressed_length (compressor_id, size); - if (!output_length) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Could not determine compression bounds for %s", - mongoc_compressor_id_to_name (compressor_id)); - bson_free (data); - return NULL; - } - - output = (char *) bson_malloc0 (output_length); - if (mongoc_compress (compressor_id, - compression_level, - data, - size, - output, - &output_length)) { - rpc_le->header.msg_len = 0; - rpc_le->compressed.original_opcode = - BSON_UINT32_FROM_LE (rpc_le->header.opcode); - rpc_le->header.opcode = MONGOC_OPCODE_COMPRESSED; - rpc_le->header.request_id = - BSON_UINT32_FROM_LE (rpc_le->header.request_id); - rpc_le->header.response_to = - BSON_UINT32_FROM_LE (rpc_le->header.response_to); - - rpc_le->compressed.uncompressed_size = size; - rpc_le->compressed.compressor_id = compressor_id; - rpc_le->compressed.compressed_message = (const uint8_t *) output; - rpc_le->compressed.compressed_message_len = output_length; - bson_free (data); - - - _mongoc_array_destroy (&cluster->iov); - _mongoc_array_init (&cluster->iov, sizeof (mongoc_iovec_t)); - _mongoc_rpc_gather (rpc_le, &cluster->iov); - _mongoc_rpc_swab_to_le (rpc_le); - return output; - } else { - MONGOC_WARNING ("Could not compress data with %s", - mongoc_compressor_id_to_name (compressor_id)); - } - bson_free (data); - bson_free (output); - return NULL; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_scatter -- - * - * Takes a (little endian) rpc struct and scatters the buffer. - * Caller should check if resulting opcode is OP_COMPRESSED - * BEFORE swabbing to native endianness. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_rpc_scatter (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen) -{ - mongoc_opcode_t opcode; - - memset (rpc, 0, sizeof *rpc); - - if (BSON_UNLIKELY (buflen < 16)) { - return false; - } - - mongoc_counter_op_ingress_total_inc (); - if (!_mongoc_rpc_scatter_header (&rpc->header, buf, 16)) { - return false; - } - - opcode = (mongoc_opcode_t) BSON_UINT32_FROM_LE (rpc->header.opcode); - - switch (opcode) { - case MONGOC_OPCODE_COMPRESSED: - mongoc_counter_op_ingress_compressed_inc (); - return _mongoc_rpc_scatter_compressed (&rpc->compressed, buf, buflen); - - case MONGOC_OPCODE_REPLY: - mongoc_counter_op_ingress_reply_inc (); - return _mongoc_rpc_scatter_reply (&rpc->reply, buf, buflen); - - case MONGOC_OPCODE_MSG: - mongoc_counter_op_ingress_msg_inc (); - return _mongoc_rpc_scatter_msg (&rpc->msg, buf, buflen); - - - /* useless, we are never *getting* these opcodes */ - case MONGOC_OPCODE_UPDATE: - return _mongoc_rpc_scatter_update (&rpc->update, buf, buflen); - - case MONGOC_OPCODE_INSERT: - return _mongoc_rpc_scatter_insert (&rpc->insert, buf, buflen); - - case MONGOC_OPCODE_QUERY: - return _mongoc_rpc_scatter_query (&rpc->query, buf, buflen); - - case MONGOC_OPCODE_GET_MORE: - return _mongoc_rpc_scatter_get_more (&rpc->get_more, buf, buflen); - - case MONGOC_OPCODE_DELETE: - return _mongoc_rpc_scatter_delete (&rpc->delete_, buf, buflen); - - case MONGOC_OPCODE_KILL_CURSORS: - return _mongoc_rpc_scatter_kill_cursors (&rpc->kill_cursors, buf, buflen); - - default: - MONGOC_WARNING ("Unknown rpc type: 0x%08x", opcode); - return false; - } -} - - -bool -_mongoc_rpc_scatter_reply_header_only (mongoc_rpc_t *rpc, - const uint8_t *buf, - size_t buflen) -{ - if (BSON_UNLIKELY (buflen < sizeof (mongoc_rpc_reply_header_t))) { - return false; - } - mongoc_counter_op_ingress_reply_inc (); - mongoc_counter_op_ingress_total_inc (); - return _mongoc_rpc_scatter_reply_header (&rpc->reply_header, buf, buflen); -} - -bool -_mongoc_rpc_get_first_document (mongoc_rpc_t *rpc, bson_t *reply) -{ - if (rpc->header.opcode == MONGOC_OPCODE_MSG) { - return _mongoc_rpc_reply_get_first_msg (&rpc->msg, reply); - } - - if (rpc->header.opcode == MONGOC_OPCODE_REPLY && - _mongoc_rpc_reply_get_first (&rpc->reply, reply)) { - return true; - } - - return false; -} - -/* Get the first BSON document from an OP_MSG reply: */ -bool -_mongoc_rpc_reply_get_first_msg (mongoc_rpc_msg_t *reply_msg, - bson_t *bson_reply) -{ - /* Note that mongo_rpc_reply_t is a union, with a mongo_rpc_msg_t field; see - the *.def files and MongoDB Wire Protocol documentation for details. */ - - int32_t document_len; - - BSON_ASSERT (0 == reply_msg->sections[0].payload_type); - - /* As per the Wire Protocol documentation, each section has a 32 bit length - field: */ - memcpy (&document_len, reply_msg->sections[0].payload.bson_document, 4); - document_len = BSON_UINT32_FROM_LE (document_len); - - bson_init_static ( - bson_reply, reply_msg->sections[0].payload.bson_document, document_len); - - return true; -} - -bool -_mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson) -{ - int32_t len; - - if (!reply->documents || reply->documents_len < 4) { - return false; - } - - memcpy (&len, reply->documents, 4); - len = BSON_UINT32_FROM_LE (len); - if (reply->documents_len < len) { - return false; - } - - return bson_init_static (bson, reply->documents, len); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_prep_command -- - * - * Prepare an RPC for mongoc_cluster_run_command_rpc. @cmd_ns and - * @cmd must not be freed or modified while the RPC is in use. - * - * Side effects: - * Fills out the RPC, including pointers into @cmd_ns and @command. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_rpc_prep_command (mongoc_rpc_t *rpc, - const char *cmd_ns, - mongoc_cmd_t *cmd) - -{ - rpc->header.msg_len = 0; - rpc->header.request_id = 0; - rpc->header.response_to = 0; - rpc->header.opcode = MONGOC_OPCODE_QUERY; - rpc->query.collection = cmd_ns; - rpc->query.skip = 0; - rpc->query.n_return = -1; - rpc->query.fields = NULL; - rpc->query.query = bson_get_data (cmd->command); - - /* Find, getMore And killCursors Commands Spec: "When sending a find command - * rather than a legacy OP_QUERY find, only the secondaryOk flag is honored." - * For other cursor-typed commands like aggregate, only secondaryOk can be - * set. Clear bits except secondaryOk; leave secondaryOk set only if it is - * already. - */ - rpc->query.flags = cmd->query_flags & MONGOC_QUERY_SECONDARY_OK; -} - /* returns true if an error was found. */ static bool @@ -1292,43 +279,17 @@ _mongoc_populate_query_error (const bson_t *doc, EXIT; } - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_check_ok -- - * - * Check if a server OP_REPLY is an error message. - * Optionally fill out a bson_error_t from the server error. - * @error_document must be an initialized bson_t or NULL. - * Does *not* check for writeConcernError. - * - * Returns: - * false if the reply is an error message, true otherwise. - * - * Side effects: - * If rpc is an error reply and @error is not NULL, set its - * domain, code, and message. - * - * If rpc is an error reply and @error_document is not NULL, - * it is reinitialized with the server reply. - * - *-------------------------------------------------------------------------- - */ - bool -_mongoc_rpc_check_ok (mongoc_rpc_t *rpc, - int32_t error_api_version, - bson_error_t *error /* OUT */, - bson_t *error_doc /* OUT */) +mcd_rpc_message_check_ok (mcd_rpc_message *rpc, + int32_t error_api_version, + bson_error_t *error /* OUT */, + bson_t *error_doc /* OUT */) { - bson_t b; + BSON_ASSERT (rpc); ENTRY; - BSON_ASSERT (rpc); - - if (rpc->header.opcode != MONGOC_OPCODE_REPLY) { + if (mcd_rpc_header_get_op_code (rpc) != MONGOC_OP_CODE_REPLY) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, @@ -1336,16 +297,20 @@ _mongoc_rpc_check_ok (mongoc_rpc_t *rpc, RETURN (false); } - if (rpc->reply.flags & MONGOC_REPLY_QUERY_FAILURE) { - if (_mongoc_rpc_get_first_document (rpc, &b)) { - _mongoc_populate_query_error (&b, error_api_version, error); + const int32_t flags = mcd_rpc_op_reply_get_response_flags (rpc); + + if (flags & MONGOC_OP_REPLY_RESPONSE_FLAG_QUERY_FAILURE) { + bson_t body; + + if (mcd_rpc_message_get_body (rpc, &body)) { + _mongoc_populate_query_error (&body, error_api_version, error); if (error_doc) { bson_destroy (error_doc); - bson_copy_to (&b, error_doc); + bson_copy_to (&body, error_doc); } - bson_destroy (&b); + bson_destroy (&body); } else { bson_set_error (error, MONGOC_ERROR_QUERY, @@ -1354,7 +319,9 @@ _mongoc_rpc_check_ok (mongoc_rpc_t *rpc, } RETURN (false); - } else if (rpc->reply.flags & MONGOC_REPLY_CURSOR_NOT_FOUND) { + } + + if (flags & MONGOC_OP_REPLY_RESPONSE_FLAG_CURSOR_NOT_FOUND) { bson_set_error (error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, @@ -1367,41 +334,129 @@ _mongoc_rpc_check_ok (mongoc_rpc_t *rpc, RETURN (true); } -/* If rpc is OP_COMPRESSED, decompress it into buffer. - * - * Assumes rpc is still in network little-endian representation (i.e. - * _mongoc_rpc_swab_to_le has not been called). - * Returns true if rpc is not OP_COMPRESSED (and is a no-op) or if decompression - * succeeds. - * Return false and sets error otherwise. - */ -bool -_mongoc_rpc_decompress_if_necessary (mongoc_rpc_t *rpc, - mongoc_buffer_t *buffer /* IN/OUT */, - bson_error_t *error /* OUT */) +void +mcd_rpc_message_egress (const mcd_rpc_message *rpc) { - uint8_t *buf = NULL; - size_t len; + // `mcd_rpc_message_egress` is expected to be called after + // `mcd_rpc_message_to_iovecs`, which converts the opCode field to + // little endian. + int32_t op_code = mcd_rpc_header_get_op_code (rpc); + op_code = bson_iter_int32_unsafe ( + &(bson_iter_t){.raw = (const uint8_t *) &op_code}); + + if (op_code == MONGOC_OP_CODE_COMPRESSED) { + mongoc_counter_op_egress_compressed_inc (); + mongoc_counter_op_egress_total_inc (); - if (BSON_UINT32_FROM_LE (rpc->header.opcode) != MONGOC_OPCODE_COMPRESSED) { - return true; + op_code = mcd_rpc_op_compressed_get_original_opcode (rpc); + op_code = bson_iter_int32_unsafe ( + &(bson_iter_t){.raw = (const uint8_t *) &op_code}); } - len = BSON_UINT32_FROM_LE (rpc->compressed.uncompressed_size) + - sizeof (mongoc_rpc_header_t); + switch (op_code) { + case MONGOC_OP_CODE_COMPRESSED: + BSON_UNREACHABLE ("invalid opcode (double compression?!)"); + break; - buf = bson_malloc0 (len); - if (!_mongoc_rpc_decompress (rpc, buf, len)) { - bson_free (buf); - bson_set_error (error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Could not decompress server reply"); - return false; + case MONGOC_OP_CODE_MSG: + mongoc_counter_op_egress_msg_inc (); + mongoc_counter_op_egress_total_inc (); + break; + + case MONGOC_OP_CODE_REPLY: + BSON_UNREACHABLE ("unexpected OP_REPLY egress"); + break; + + case MONGOC_OP_CODE_UPDATE: + mongoc_counter_op_egress_update_inc (); + mongoc_counter_op_egress_total_inc (); + break; + + case MONGOC_OP_CODE_INSERT: + mongoc_counter_op_egress_insert_inc (); + mongoc_counter_op_egress_total_inc (); + break; + + case MONGOC_OP_CODE_QUERY: + mongoc_counter_op_egress_query_inc (); + mongoc_counter_op_egress_total_inc (); + break; + + case MONGOC_OP_CODE_GET_MORE: + mongoc_counter_op_egress_getmore_inc (); + mongoc_counter_op_egress_total_inc (); + break; + + case MONGOC_OP_CODE_DELETE: + mongoc_counter_op_egress_delete_inc (); + mongoc_counter_op_egress_total_inc (); + break; + + case MONGOC_OP_CODE_KILL_CURSORS: + mongoc_counter_op_egress_killcursors_inc (); + mongoc_counter_op_egress_total_inc (); + break; + + default: + BSON_UNREACHABLE ("invalid opcode"); } +} - _mongoc_buffer_destroy (buffer); - _mongoc_buffer_init (buffer, buf, len, NULL, NULL); +void +mcd_rpc_message_ingress (const mcd_rpc_message *rpc) +{ + // `mcd_rpc_message_ingress` is expected be called after + // `mcd_rpc_message_from_data`, which converts the opCode field to native + // endian. + int32_t op_code = mcd_rpc_header_get_op_code (rpc); + + if (op_code == MONGOC_OP_CODE_COMPRESSED) { + mongoc_counter_op_ingress_compressed_inc (); + mongoc_counter_op_ingress_total_inc (); - return true; + op_code = mcd_rpc_op_compressed_get_original_opcode (rpc); + } + + switch (op_code) { + case MONGOC_OP_CODE_COMPRESSED: + BSON_UNREACHABLE ("invalid opcode (double compression?!)"); + break; + + case MONGOC_OP_CODE_MSG: + mongoc_counter_op_ingress_msg_inc (); + mongoc_counter_op_ingress_total_inc (); + break; + + case MONGOC_OP_CODE_REPLY: + mongoc_counter_op_ingress_reply_inc (); + mongoc_counter_op_ingress_total_inc (); + break; + + case MONGOC_OP_CODE_UPDATE: + BSON_UNREACHABLE ("unexpected OP_UPDATE ingress"); + break; + + case MONGOC_OP_CODE_INSERT: + BSON_UNREACHABLE ("unexpected OP_INSERT ingress"); + break; + + case MONGOC_OP_CODE_QUERY: + BSON_UNREACHABLE ("unexpected OP_QUERY ingress"); + break; + + case MONGOC_OP_CODE_GET_MORE: + BSON_UNREACHABLE ("unexpected OP_GET_MORE ingress"); + break; + + case MONGOC_OP_CODE_DELETE: + BSON_UNREACHABLE ("unexpected OP_DELETE ingress"); + break; + + case MONGOC_OP_CODE_KILL_CURSORS: + BSON_UNREACHABLE ("unexpected OP_KILL_CURSORS ingress"); + break; + + default: + BSON_UNREACHABLE ("invalid opcode"); + } } diff --git a/src/mongoc/mongoc-scram-private.h b/src/mongoc/mongoc-scram-private.h index 75f80797..6b1ca136 100644 --- a/src/mongoc/mongoc-scram-private.h +++ b/src/mongoc/mongoc-scram-private.h @@ -38,22 +38,17 @@ BSON_BEGIN_DECLS #define MONGOC_SCRAM_B64_HASH_MAX_SIZE \ MONGOC_SCRAM_B64_ENCODED_SIZE (MONGOC_SCRAM_HASH_MAX_SIZE) -typedef struct _mongoc_scram_cache_t { - /* pre-secrets */ - char *hashed_password; - uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE]; - uint32_t iterations; - /* secrets */ - uint8_t client_key[MONGOC_SCRAM_HASH_MAX_SIZE]; - uint8_t server_key[MONGOC_SCRAM_HASH_MAX_SIZE]; - uint8_t salted_password[MONGOC_SCRAM_HASH_MAX_SIZE]; -} mongoc_scram_cache_t; +enum { + /* It is unlikely that there will be more than 64 different user accounts + * used in a single process */ + MONGOC_SCRAM_CACHE_SIZE = 64, +}; typedef struct _mongoc_scram_t { int step; char *user; char *pass; - char *hashed_password; + char hashed_password[MONGOC_SCRAM_HASH_MAX_SIZE]; uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE]; uint32_t iterations; uint8_t client_key[MONGOC_SCRAM_HASH_MAX_SIZE]; @@ -67,7 +62,6 @@ typedef struct _mongoc_scram_t { #ifdef MONGOC_ENABLE_CRYPTO mongoc_crypto_t crypto; #endif - mongoc_scram_cache_t *cache; } mongoc_scram_t; #ifdef MONGOC_ENABLE_CRYPTO @@ -75,12 +69,6 @@ void _mongoc_scram_init (mongoc_scram_t *scram, mongoc_crypto_hash_algorithm_t algo); #endif -mongoc_scram_cache_t * -_mongoc_scram_get_cache (mongoc_scram_t *scram); - -void -_mongoc_scram_set_cache (mongoc_scram_t *scram, mongoc_scram_cache_t *cache); - void _mongoc_scram_set_pass (mongoc_scram_t *scram, const char *pass); @@ -109,19 +97,335 @@ _mongoc_scram_step (mongoc_scram_t *scram, uint32_t *outbuflen, bson_error_t *error); -void -_mongoc_scram_cache_destroy (mongoc_scram_cache_t *cache); - /* returns false if this string does not need SASLPrep. It returns true * conservatively, if str might need to be SASLPrep'ed. */ bool _mongoc_sasl_prep_required (const char *str); /* returns the output of SASLPrep as a new string which must be freed. Returns - * null on error and sets err. - * `name` should be "username" or "password". */ + * null on error and sets err. */ char * -_mongoc_sasl_prep (const char *in_utf8, int in_utf8_len, bson_error_t *err); +_mongoc_sasl_prep (const char *in_utf8, bson_error_t *err); + +/* returns the byte length of the first UTF-8 code point in `s`. + * _mongoc_utf8_char_length is exposed for testing */ +size_t +_mongoc_utf8_char_length (const char *s); + +/* returns the byte length of the UTF-8 string. Returns -1 if `s` is not a valid + * UTF-8 string. + * _mongoc_utf8_string_length is exposed for testing. */ +ssize_t +_mongoc_utf8_string_length (const char *s); + +/* returns the first Unicode code point in `c`. Returns 0 if length is 0. + * `c` must be a valid UTF-8 string. + * _mongoc_utf8_get_first_code_point is exposed for testing. */ +uint32_t +_mongoc_utf8_get_first_code_point (const char *c, size_t length); + +/* the tables below all come from RFC 3454. They are all range tables, with + * value 2*n being the lower bound, and value 2*n + 1 being the upper bound. + * Both bounds are exclusive. + */ + +/* A.1 Unassigned code points in Unicode 3.2 + * these characters are not allowed for SASLPrep + */ +static const uint32_t unassigned_codepoint_ranges[] = { + 0x0221, 0x0221, 0x0234, 0x024F, 0x02AE, 0x02AF, 0x02EF, 0x02FF, + 0x0350, 0x035F, 0x0370, 0x0373, 0x0376, 0x0379, 0x037B, 0x037D, + 0x037F, 0x0383, 0x038B, 0x038B, 0x038D, 0x038D, 0x03A2, 0x03A2, + 0x03CF, 0x03CF, 0x03F7, 0x03FF, 0x0487, 0x0487, 0x04CF, 0x04CF, + 0x04F6, 0x04F7, 0x04FA, 0x04FF, 0x0510, 0x0530, 0x0557, 0x0558, + 0x0560, 0x0560, 0x0588, 0x0588, 0x058B, 0x0590, 0x05A2, 0x05A2, + 0x05BA, 0x05BA, 0x05C5, 0x05CF, 0x05EB, 0x05EF, 0x05F5, 0x060B, + 0x060D, 0x061A, 0x061C, 0x061E, 0x0620, 0x0620, 0x063B, 0x063F, + 0x0656, 0x065F, 0x06EE, 0x06EF, 0x06FF, 0x06FF, 0x070E, 0x070E, + 0x072D, 0x072F, 0x074B, 0x077F, 0x07B2, 0x0900, 0x0904, 0x0904, + 0x093A, 0x093B, 0x094E, 0x094F, 0x0955, 0x0957, 0x0971, 0x0980, + 0x0984, 0x0984, 0x098D, 0x098E, 0x0991, 0x0992, 0x09A9, 0x09A9, + 0x09B1, 0x09B1, 0x09B3, 0x09B5, 0x09BA, 0x09BB, 0x09BD, 0x09BD, + 0x09C5, 0x09C6, 0x09C9, 0x09CA, 0x09CE, 0x09D6, 0x09D8, 0x09DB, + 0x09DE, 0x09DE, 0x09E4, 0x09E5, 0x09FB, 0x0A01, 0x0A03, 0x0A04, + 0x0A0B, 0x0A0E, 0x0A11, 0x0A12, 0x0A29, 0x0A29, 0x0A31, 0x0A31, + 0x0A34, 0x0A34, 0x0A37, 0x0A37, 0x0A3A, 0x0A3B, 0x0A3D, 0x0A3D, + 0x0A43, 0x0A46, 0x0A49, 0x0A4A, 0x0A4E, 0x0A58, 0x0A5D, 0x0A5D, + 0x0A5F, 0x0A65, 0x0A75, 0x0A80, 0x0A84, 0x0A84, 0x0A8C, 0x0A8C, + 0x0A8E, 0x0A8E, 0x0A92, 0x0A92, 0x0AA9, 0x0AA9, 0x0AB1, 0x0AB1, + 0x0AB4, 0x0AB4, 0x0ABA, 0x0ABB, 0x0AC6, 0x0AC6, 0x0ACA, 0x0ACA, + 0x0ACE, 0x0ACF, 0x0AD1, 0x0ADF, 0x0AE1, 0x0AE5, 0x0AF0, 0x0B00, + 0x0B04, 0x0B04, 0x0B0D, 0x0B0E, 0x0B11, 0x0B12, 0x0B29, 0x0B29, + 0x0B31, 0x0B31, 0x0B34, 0x0B35, 0x0B3A, 0x0B3B, 0x0B44, 0x0B46, + 0x0B49, 0x0B4A, 0x0B4E, 0x0B55, 0x0B58, 0x0B5B, 0x0B5E, 0x0B5E, + 0x0B62, 0x0B65, 0x0B71, 0x0B81, 0x0B84, 0x0B84, 0x0B8B, 0x0B8D, + 0x0B91, 0x0B91, 0x0B96, 0x0B98, 0x0B9B, 0x0B9B, 0x0B9D, 0x0B9D, + 0x0BA0, 0x0BA2, 0x0BA5, 0x0BA7, 0x0BAB, 0x0BAD, 0x0BB6, 0x0BB6, + 0x0BBA, 0x0BBD, 0x0BC3, 0x0BC5, 0x0BC9, 0x0BC9, 0x0BCE, 0x0BD6, + 0x0BD8, 0x0BE6, 0x0BF3, 0x0C00, 0x0C04, 0x0C04, 0x0C0D, 0x0C0D, + 0x0C11, 0x0C11, 0x0C29, 0x0C29, 0x0C34, 0x0C34, 0x0C3A, 0x0C3D, + 0x0C45, 0x0C45, 0x0C49, 0x0C49, 0x0C4E, 0x0C54, 0x0C57, 0x0C5F, + 0x0C62, 0x0C65, 0x0C70, 0x0C81, 0x0C84, 0x0C84, 0x0C8D, 0x0C8D, + 0x0C91, 0x0C91, 0x0CA9, 0x0CA9, 0x0CB4, 0x0CB4, 0x0CBA, 0x0CBD, + 0x0CC5, 0x0CC5, 0x0CC9, 0x0CC9, 0x0CCE, 0x0CD4, 0x0CD7, 0x0CDD, + 0x0CDF, 0x0CDF, 0x0CE2, 0x0CE5, 0x0CF0, 0x0D01, 0x0D04, 0x0D04, + 0x0D0D, 0x0D0D, 0x0D11, 0x0D11, 0x0D29, 0x0D29, 0x0D3A, 0x0D3D, + 0x0D44, 0x0D45, 0x0D49, 0x0D49, 0x0D4E, 0x0D56, 0x0D58, 0x0D5F, + 0x0D62, 0x0D65, 0x0D70, 0x0D81, 0x0D84, 0x0D84, 0x0D97, 0x0D99, + 0x0DB2, 0x0DB2, 0x0DBC, 0x0DBC, 0x0DBE, 0x0DBF, 0x0DC7, 0x0DC9, + 0x0DCB, 0x0DCE, 0x0DD5, 0x0DD5, 0x0DD7, 0x0DD7, 0x0DE0, 0x0DF1, + 0x0DF5, 0x0E00, 0x0E3B, 0x0E3E, 0x0E5C, 0x0E80, 0x0E83, 0x0E83, + 0x0E85, 0x0E86, 0x0E89, 0x0E89, 0x0E8B, 0x0E8C, 0x0E8E, 0x0E93, + 0x0E98, 0x0E98, 0x0EA0, 0x0EA0, 0x0EA4, 0x0EA4, 0x0EA6, 0x0EA6, + 0x0EA8, 0x0EA9, 0x0EAC, 0x0EAC, 0x0EBA, 0x0EBA, 0x0EBE, 0x0EBF, + 0x0EC5, 0x0EC5, 0x0EC7, 0x0EC7, 0x0ECE, 0x0ECF, 0x0EDA, 0x0EDB, + 0x0EDE, 0x0EFF, 0x0F48, 0x0F48, 0x0F6B, 0x0F70, 0x0F8C, 0x0F8F, + 0x0F98, 0x0F98, 0x0FBD, 0x0FBD, 0x0FCD, 0x0FCE, 0x0FD0, 0x0FFF, + 0x1022, 0x1022, 0x1028, 0x1028, 0x102B, 0x102B, 0x1033, 0x1035, + 0x103A, 0x103F, 0x105A, 0x109F, 0x10C6, 0x10CF, 0x10F9, 0x10FA, + 0x10FC, 0x10FF, 0x115A, 0x115E, 0x11A3, 0x11A7, 0x11FA, 0x11FF, + 0x1207, 0x1207, 0x1247, 0x1247, 0x1249, 0x1249, 0x124E, 0x124F, + 0x1257, 0x1257, 0x1259, 0x1259, 0x125E, 0x125F, 0x1287, 0x1287, + 0x1289, 0x1289, 0x128E, 0x128F, 0x12AF, 0x12AF, 0x12B1, 0x12B1, + 0x12B6, 0x12B7, 0x12BF, 0x12BF, 0x12C1, 0x12C1, 0x12C6, 0x12C7, + 0x12CF, 0x12CF, 0x12D7, 0x12D7, 0x12EF, 0x12EF, 0x130F, 0x130F, + 0x1311, 0x1311, 0x1316, 0x1317, 0x131F, 0x131F, 0x1347, 0x1347, + 0x135B, 0x1360, 0x137D, 0x139F, 0x13F5, 0x1400, 0x1677, 0x167F, + 0x169D, 0x169F, 0x16F1, 0x16FF, 0x170D, 0x170D, 0x1715, 0x171F, + 0x1737, 0x173F, 0x1754, 0x175F, 0x176D, 0x176D, 0x1771, 0x1771, + 0x1774, 0x177F, 0x17DD, 0x17DF, 0x17EA, 0x17FF, 0x180F, 0x180F, + 0x181A, 0x181F, 0x1878, 0x187F, 0x18AA, 0x1DFF, 0x1E9C, 0x1E9F, + 0x1EFA, 0x1EFF, 0x1F16, 0x1F17, 0x1F1E, 0x1F1F, 0x1F46, 0x1F47, + 0x1F4E, 0x1F4F, 0x1F58, 0x1F58, 0x1F5A, 0x1F5A, 0x1F5C, 0x1F5C, + 0x1F5E, 0x1F5E, 0x1F7E, 0x1F7F, 0x1FB5, 0x1FB5, 0x1FC5, 0x1FC5, + 0x1FD4, 0x1FD5, 0x1FDC, 0x1FDC, 0x1FF0, 0x1FF1, 0x1FF5, 0x1FF5, + 0x1FFF, 0x1FFF, 0x2053, 0x2056, 0x2058, 0x205E, 0x2064, 0x2069, + 0x2072, 0x2073, 0x208F, 0x209F, 0x20B2, 0x20CF, 0x20EB, 0x20FF, + 0x213B, 0x213C, 0x214C, 0x2152, 0x2184, 0x218F, 0x23CF, 0x23FF, + 0x2427, 0x243F, 0x244B, 0x245F, 0x24FF, 0x24FF, 0x2614, 0x2615, + 0x2618, 0x2618, 0x267E, 0x267F, 0x268A, 0x2700, 0x2705, 0x2705, + 0x270A, 0x270B, 0x2728, 0x2728, 0x274C, 0x274C, 0x274E, 0x274E, + 0x2753, 0x2755, 0x2757, 0x2757, 0x275F, 0x2760, 0x2795, 0x2797, + 0x27B0, 0x27B0, 0x27BF, 0x27CF, 0x27EC, 0x27EF, 0x2B00, 0x2E7F, + 0x2E9A, 0x2E9A, 0x2EF4, 0x2EFF, 0x2FD6, 0x2FEF, 0x2FFC, 0x2FFF, + 0x3040, 0x3040, 0x3097, 0x3098, 0x3100, 0x3104, 0x312D, 0x3130, + 0x318F, 0x318F, 0x31B8, 0x31EF, 0x321D, 0x321F, 0x3244, 0x3250, + 0x327C, 0x327E, 0x32CC, 0x32CF, 0x32FF, 0x32FF, 0x3377, 0x337A, + 0x33DE, 0x33DF, 0x33FF, 0x33FF, 0x4DB6, 0x4DFF, 0x9FA6, 0x9FFF, + 0xA48D, 0xA48F, 0xA4C7, 0xABFF, 0xD7A4, 0xD7FF, 0xFA2E, 0xFA2F, + 0xFA6B, 0xFAFF, 0xFB07, 0xFB12, 0xFB18, 0xFB1C, 0xFB37, 0xFB37, + 0xFB3D, 0xFB3D, 0xFB3F, 0xFB3F, 0xFB42, 0xFB42, 0xFB45, 0xFB45, + 0xFBB2, 0xFBD2, 0xFD40, 0xFD4F, 0xFD90, 0xFD91, 0xFDC8, 0xFDCF, + 0xFDFD, 0xFDFF, 0xFE10, 0xFE1F, 0xFE24, 0xFE2F, 0xFE47, 0xFE48, + 0xFE53, 0xFE53, 0xFE67, 0xFE67, 0xFE6C, 0xFE6F, 0xFE75, 0xFE75, + 0xFEFD, 0xFEFE, 0xFF00, 0xFF00, 0xFFBF, 0xFFC1, 0xFFC8, 0xFFC9, + 0xFFD0, 0xFFD1, 0xFFD8, 0xFFD9, 0xFFDD, 0xFFDF, 0xFFE7, 0xFFE7, + 0xFFEF, 0xFFF8, 0x10000, 0x102FF, 0x1031F, 0x1031F, 0x10324, 0x1032F, + 0x1034B, 0x103FF, 0x10426, 0x10427, 0x1044E, 0x1CFFF, 0x1D0F6, 0x1D0FF, + 0x1D127, 0x1D129, 0x1D1DE, 0x1D3FF, 0x1D455, 0x1D455, 0x1D49D, 0x1D49D, + 0x1D4A0, 0x1D4A1, 0x1D4A3, 0x1D4A4, 0x1D4A7, 0x1D4A8, 0x1D4AD, 0x1D4AD, + 0x1D4BA, 0x1D4BA, 0x1D4BC, 0x1D4BC, 0x1D4C1, 0x1D4C1, 0x1D4C4, 0x1D4C4, + 0x1D506, 0x1D506, 0x1D50B, 0x1D50C, 0x1D515, 0x1D515, 0x1D51D, 0x1D51D, + 0x1D53A, 0x1D53A, 0x1D53F, 0x1D53F, 0x1D545, 0x1D545, 0x1D547, 0x1D549, + 0x1D551, 0x1D551, 0x1D6A4, 0x1D6A7, 0x1D7CA, 0x1D7CD, 0x1D800, 0x1FFFD, + 0x2A6D7, 0x2F7FF, 0x2FA1E, 0x2FFFD, 0x30000, 0x3FFFD, 0x40000, 0x4FFFD, + 0x50000, 0x5FFFD, 0x60000, 0x6FFFD, 0x70000, 0x7FFFD, 0x80000, 0x8FFFD, + 0x90000, 0x9FFFD, 0xA0000, 0xAFFFD, 0xB0000, 0xBFFFD, 0xC0000, 0xCFFFD, + 0xD0000, 0xDFFFD, 0xE0000, 0xE0000, 0xE0002, 0xE001F, 0xE0080, 0xEFFFD}; + +/* + * Table B.1 Commonly mapped to nothing + * these are all of the characters that will be mapped to nothing. + */ +static const uint32_t commonly_mapped_to_nothing_ranges[] = {0x00AD, + 0x00AD, + 0x034F, + 0x034F, + 0x1806, + 0x1806, + 0x180B, + 0x180D, + 0x200B, + 0x200D, + 0x2060, + 0x2060, + 0xFE00, + 0xFE0F, + 0xFEFF, + 0xFEFF}; + +/* + * Table C.1.2 Non-ASCII space characters + * these are all of the characters that will be mapped to the space character. + * (0x0020) + */ +static const uint32_t non_ascii_space_character_ranges[] = {0x00A0, + 0x00A0, + 0x1680, + 0x1680, + 0x2000, + 0x200B, + 0x202F, + 0x202F, + 0x205F, + 0x205F, + 0x3000, + 0x3000}; + +/* + * these are all of the characters that are "prohibited output" for SASLprep. + * The tables that they come from are listed. + */ +static const uint32_t prohibited_output_ranges[] = { + 0x0000, 0x001F, /* C.2.1 */ + 0x007F, 0x00A0, /* C.1.2, C.2.1, C.2.2 */ + 0x0340, 0x0341, /* C.8 */ + 0x06DD, 0x06DD, /* C.2.2 */ + 0x070F, 0x070F, /* C.2.2 */ + 0x1680, 0x1680, /* C.1.2 */ + 0x180E, 0x180E, /* C.2.2 */ + 0x2000, 0x200F, /* C.1.2, C.2.2, C.8 */ + 0x2028, 0x202F, /* C.1.2, C.2.2, C.8 */ + 0x205F, 0x2063, /* C.1.2, C.2.2 */ + 0x206A, 0x206F, /* C.2.2, C.8 */ + 0x2FF0, 0x2FFB, /* C.7 */ + 0x3000, 0x3000, /* C.1.2 */ + 0xD800, 0xF8FF, /* C.3, C.5 */ + 0xFDD0, 0xFDEF, /* C.4 */ + 0xFEFF, 0xFEFF, /* C.2.2 */ + 0xFFF9, 0xFFFF, /* C.2.2, C.4, C.6 */ + 0x1D173, 0x1D17A, /* C.2.2 */ + 0x1FFFE, 0x1FFFF, /* C.4 */ + 0x2FFFE, 0x2FFFF, /* C.4 */ + 0x3FFFE, 0x3FFFF, /* C.4 */ + 0x4FFFE, 0x4FFFF, /* C.4 */ + 0x5FFFE, 0x5FFFF, /* C.4 */ + 0x6FFFE, 0x6FFFF, /* C.4 */ + 0x7FFFE, 0x7FFFF, /* C.4 */ + 0x8FFFE, 0x8FFFF, /* C.4 */ + 0x9FFFE, 0x9FFFF, /* C.4 */ + 0xAFFFE, 0xAFFFF, /* C.4 */ + 0xBFFFE, 0xBFFFF, /* C.4 */ + 0xCFFFE, 0xCFFFF, /* C.4 */ + 0xDFFFE, 0xDFFFF, /* C.4 */ + 0xE0001, 0xE0001, /* C.9 */ + 0xE0020, 0xE007F, /* C.9 */ + 0xEFFFE, 0xEFFFF, /* C.4 */ + 0xF0000, 0xFFFFF, /* C.3, C.4 */ + 0x100000, 0x10FFFF /* C.3, C.4 */ +}; + +/* D.1 Characters with bidirectional property "R" or "AL" + * any string that contains one of these characters cannot contain a character + * with bidirectional property "L". + */ + +static const uint32_t RandALCat_bidi_ranges[] = { + 0x05BE, 0x05BE, 0x05C0, 0x05C0, 0x05C3, 0x05C3, 0x05D0, 0x05EA, 0x05F0, + 0x05F4, 0x061B, 0x061B, 0x061F, 0x061F, 0x0621, 0x063A, 0x0640, 0x064A, + 0x066D, 0x066F, 0x0671, 0x06D5, 0x06DD, 0x06DD, 0x06E5, 0x06E6, 0x06FA, + 0x06FE, 0x0700, 0x070D, 0x0710, 0x0710, 0x0712, 0x072C, 0x0780, 0x07A5, + 0x07B1, 0x07B1, 0x200F, 0x200F, 0xFB1D, 0xFB1D, 0xFB1F, 0xFB28, 0xFB2A, + 0xFB36, 0xFB38, 0xFB3C, 0xFB3E, 0xFB3E, 0xFB40, 0xFB41, 0xFB43, 0xFB44, + 0xFB46, 0xFBB1, 0xFBD3, 0xFD3D, 0xFD50, 0xFD8F, 0xFD92, 0xFDC7, 0xFDF0, + 0xFDFC, 0xFE70, 0xFE74, 0xFE76, 0xFEFC}; + +/* D.2 Characters with bidirectional property "L" + * any string that contains one of these characters cannot contain a character + * with bidirectional property "R" or "AL". + * */ +static const uint32_t LCat_bidi_ranges[] = { + 0x0041, 0x005A, 0x0061, 0x007A, 0x00AA, 0x00AA, 0x00B5, 0x00B5, + 0x00BA, 0x00BA, 0x00C0, 0x00D6, 0x00D8, 0x00F6, 0x00F8, 0x0220, + 0x0222, 0x0233, 0x0250, 0x02AD, 0x02B0, 0x02B8, 0x02BB, 0x02C1, + 0x02D0, 0x02D1, 0x02E0, 0x02E4, 0x02EE, 0x02EE, 0x037A, 0x037A, + 0x0386, 0x0386, 0x0388, 0x038A, 0x038C, 0x038C, 0x038E, 0x03A1, + 0x03A3, 0x03CE, 0x03D0, 0x03F5, 0x0400, 0x0482, 0x048A, 0x04CE, + 0x04D0, 0x04F5, 0x04F8, 0x04F9, 0x0500, 0x050F, 0x0531, 0x0556, + 0x0559, 0x055F, 0x0561, 0x0587, 0x0589, 0x0589, 0x0903, 0x0903, + 0x0905, 0x0939, 0x093D, 0x0940, 0x0949, 0x094C, 0x0950, 0x0950, + 0x0958, 0x0961, 0x0964, 0x0970, 0x0982, 0x0983, 0x0985, 0x098C, + 0x098F, 0x0990, 0x0993, 0x09A8, 0x09AA, 0x09B0, 0x09B2, 0x09B2, + 0x09B6, 0x09B9, 0x09BE, 0x09C0, 0x09C7, 0x09C8, 0x09CB, 0x09CC, + 0x09D7, 0x09D7, 0x09DC, 0x09DD, 0x09DF, 0x09E1, 0x09E6, 0x09F1, + 0x09F4, 0x09FA, 0x0A05, 0x0A0A, 0x0A0F, 0x0A10, 0x0A13, 0x0A28, + 0x0A2A, 0x0A30, 0x0A32, 0x0A33, 0x0A35, 0x0A36, 0x0A38, 0x0A39, + 0x0A3E, 0x0A40, 0x0A59, 0x0A5C, 0x0A5E, 0x0A5E, 0x0A66, 0x0A6F, + 0x0A72, 0x0A74, 0x0A83, 0x0A83, 0x0A85, 0x0A8B, 0x0A8D, 0x0A8D, + 0x0A8F, 0x0A91, 0x0A93, 0x0AA8, 0x0AAA, 0x0AB0, 0x0AB2, 0x0AB3, + 0x0AB5, 0x0AB9, 0x0ABD, 0x0AC0, 0x0AC9, 0x0AC9, 0x0ACB, 0x0ACC, + 0x0AD0, 0x0AD0, 0x0AE0, 0x0AE0, 0x0AE6, 0x0AEF, 0x0B02, 0x0B03, + 0x0B05, 0x0B0C, 0x0B0F, 0x0B10, 0x0B13, 0x0B28, 0x0B2A, 0x0B30, + 0x0B32, 0x0B33, 0x0B36, 0x0B39, 0x0B3D, 0x0B3E, 0x0B40, 0x0B40, + 0x0B47, 0x0B48, 0x0B4B, 0x0B4C, 0x0B57, 0x0B57, 0x0B5C, 0x0B5D, + 0x0B5F, 0x0B61, 0x0B66, 0x0B70, 0x0B83, 0x0B83, 0x0B85, 0x0B8A, + 0x0B8E, 0x0B90, 0x0B92, 0x0B95, 0x0B99, 0x0B9A, 0x0B9C, 0x0B9C, + 0x0B9E, 0x0B9F, 0x0BA3, 0x0BA4, 0x0BA8, 0x0BAA, 0x0BAE, 0x0BB5, + 0x0BB7, 0x0BB9, 0x0BBE, 0x0BBF, 0x0BC1, 0x0BC2, 0x0BC6, 0x0BC8, + 0x0BCA, 0x0BCC, 0x0BD7, 0x0BD7, 0x0BE7, 0x0BF2, 0x0C01, 0x0C03, + 0x0C05, 0x0C0C, 0x0C0E, 0x0C10, 0x0C12, 0x0C28, 0x0C2A, 0x0C33, + 0x0C35, 0x0C39, 0x0C41, 0x0C44, 0x0C60, 0x0C61, 0x0C66, 0x0C6F, + 0x0C82, 0x0C83, 0x0C85, 0x0C8C, 0x0C8E, 0x0C90, 0x0C92, 0x0CA8, + 0x0CAA, 0x0CB3, 0x0CB5, 0x0CB9, 0x0CBE, 0x0CBE, 0x0CC0, 0x0CC4, + 0x0CC7, 0x0CC8, 0x0CCA, 0x0CCB, 0x0CD5, 0x0CD6, 0x0CDE, 0x0CDE, + 0x0CE0, 0x0CE1, 0x0CE6, 0x0CEF, 0x0D02, 0x0D03, 0x0D05, 0x0D0C, + 0x0D0E, 0x0D10, 0x0D12, 0x0D28, 0x0D2A, 0x0D39, 0x0D3E, 0x0D40, + 0x0D46, 0x0D48, 0x0D4A, 0x0D4C, 0x0D57, 0x0D57, 0x0D60, 0x0D61, + 0x0D66, 0x0D6F, 0x0D82, 0x0D83, 0x0D85, 0x0D96, 0x0D9A, 0x0DB1, + 0x0DB3, 0x0DBB, 0x0DBD, 0x0DBD, 0x0DC0, 0x0DC6, 0x0DCF, 0x0DD1, + 0x0DD8, 0x0DDF, 0x0DF2, 0x0DF4, 0x0E01, 0x0E30, 0x0E32, 0x0E33, + 0x0E40, 0x0E46, 0x0E4F, 0x0E5B, 0x0E81, 0x0E82, 0x0E84, 0x0E84, + 0x0E87, 0x0E88, 0x0E8A, 0x0E8A, 0x0E8D, 0x0E8D, 0x0E94, 0x0E97, + 0x0E99, 0x0E9F, 0x0EA1, 0x0EA3, 0x0EA5, 0x0EA5, 0x0EA7, 0x0EA7, + 0x0EAA, 0x0EAB, 0x0EAD, 0x0EB0, 0x0EB2, 0x0EB3, 0x0EBD, 0x0EBD, + 0x0EC0, 0x0EC4, 0x0EC6, 0x0EC6, 0x0ED0, 0x0ED9, 0x0EDC, 0x0EDD, + 0x0F00, 0x0F17, 0x0F1A, 0x0F34, 0x0F36, 0x0F36, 0x0F38, 0x0F38, + 0x0F3E, 0x0F47, 0x0F49, 0x0F6A, 0x0F7F, 0x0F7F, 0x0F85, 0x0F85, + 0x0F88, 0x0F8B, 0x0FBE, 0x0FC5, 0x0FC7, 0x0FCC, 0x0FCF, 0x0FCF, + 0x1000, 0x1021, 0x1023, 0x1027, 0x1029, 0x102A, 0x102C, 0x102C, + 0x1031, 0x1031, 0x1038, 0x1038, 0x1040, 0x1057, 0x10A0, 0x10C5, + 0x10D0, 0x10F8, 0x10FB, 0x10FB, 0x1100, 0x1159, 0x115F, 0x11A2, + 0x11A8, 0x11F9, 0x1200, 0x1206, 0x1208, 0x1246, 0x1248, 0x1248, + 0x124A, 0x124D, 0x1250, 0x1256, 0x1258, 0x1258, 0x125A, 0x125D, + 0x1260, 0x1286, 0x1288, 0x1288, 0x128A, 0x128D, 0x1290, 0x12AE, + 0x12B0, 0x12B0, 0x12B2, 0x12B5, 0x12B8, 0x12BE, 0x12C0, 0x12C0, + 0x12C2, 0x12C5, 0x12C8, 0x12CE, 0x12D0, 0x12D6, 0x12D8, 0x12EE, + 0x12F0, 0x130E, 0x1310, 0x1310, 0x1312, 0x1315, 0x1318, 0x131E, + 0x1320, 0x1346, 0x1348, 0x135A, 0x1361, 0x137C, 0x13A0, 0x13F4, + 0x1401, 0x1676, 0x1681, 0x169A, 0x16A0, 0x16F0, 0x1700, 0x170C, + 0x170E, 0x1711, 0x1720, 0x1731, 0x1735, 0x1736, 0x1740, 0x1751, + 0x1760, 0x176C, 0x176E, 0x1770, 0x1780, 0x17B6, 0x17BE, 0x17C5, + 0x17C7, 0x17C8, 0x17D4, 0x17DA, 0x17DC, 0x17DC, 0x17E0, 0x17E9, + 0x1810, 0x1819, 0x1820, 0x1877, 0x1880, 0x18A8, 0x1E00, 0x1E9B, + 0x1EA0, 0x1EF9, 0x1F00, 0x1F15, 0x1F18, 0x1F1D, 0x1F20, 0x1F45, + 0x1F48, 0x1F4D, 0x1F50, 0x1F57, 0x1F59, 0x1F59, 0x1F5B, 0x1F5B, + 0x1F5D, 0x1F5D, 0x1F5F, 0x1F7D, 0x1F80, 0x1FB4, 0x1FB6, 0x1FBC, + 0x1FBE, 0x1FBE, 0x1FC2, 0x1FC4, 0x1FC6, 0x1FCC, 0x1FD0, 0x1FD3, + 0x1FD6, 0x1FDB, 0x1FE0, 0x1FEC, 0x1FF2, 0x1FF4, 0x1FF6, 0x1FFC, + 0x200E, 0x200E, 0x2071, 0x2071, 0x207F, 0x207F, 0x2102, 0x2102, + 0x2107, 0x2107, 0x210A, 0x2113, 0x2115, 0x2115, 0x2119, 0x211D, + 0x2124, 0x2124, 0x2126, 0x2126, 0x2128, 0x2128, 0x212A, 0x212D, + 0x212F, 0x2131, 0x2133, 0x2139, 0x213D, 0x213F, 0x2145, 0x2149, + 0x2160, 0x2183, 0x2336, 0x237A, 0x2395, 0x2395, 0x249C, 0x24E9, + 0x3005, 0x3007, 0x3021, 0x3029, 0x3031, 0x3035, 0x3038, 0x303C, + 0x3041, 0x3096, 0x309D, 0x309F, 0x30A1, 0x30FA, 0x30FC, 0x30FF, + 0x3105, 0x312C, 0x3131, 0x318E, 0x3190, 0x31B7, 0x31F0, 0x321C, + 0x3220, 0x3243, 0x3260, 0x327B, 0x327F, 0x32B0, 0x32C0, 0x32CB, + 0x32D0, 0x32FE, 0x3300, 0x3376, 0x337B, 0x33DD, 0x33E0, 0x33FE, + 0x3400, 0x4DB5, 0x4E00, 0x9FA5, 0xA000, 0xA48C, 0xAC00, 0xD7A3, + 0xD800, 0xFA2D, 0xFA30, 0xFA6A, 0xFB00, 0xFB06, 0xFB13, 0xFB17, + 0xFF21, 0xFF3A, 0xFF41, 0xFF5A, 0xFF66, 0xFFBE, 0xFFC2, 0xFFC7, + 0xFFCA, 0xFFCF, 0xFFD2, 0xFFD7, 0xFFDA, 0xFFDC, 0x10300, 0x1031E, + 0x10320, 0x10323, 0x10330, 0x1034A, 0x10400, 0x10425, 0x10428, 0x1044D, + 0x1D000, 0x1D0F5, 0x1D100, 0x1D126, 0x1D12A, 0x1D166, 0x1D16A, 0x1D172, + 0x1D183, 0x1D184, 0x1D18C, 0x1D1A9, 0x1D1AE, 0x1D1DD, 0x1D400, 0x1D454, + 0x1D456, 0x1D49C, 0x1D49E, 0x1D49F, 0x1D4A2, 0x1D4A2, 0x1D4A5, 0x1D4A6, + 0x1D4A9, 0x1D4AC, 0x1D4AE, 0x1D4B9, 0x1D4BB, 0x1D4BB, 0x1D4BD, 0x1D4C0, + 0x1D4C2, 0x1D4C3, 0x1D4C5, 0x1D505, 0x1D507, 0x1D50A, 0x1D50D, 0x1D514, + 0x1D516, 0x1D51C, 0x1D51E, 0x1D539, 0x1D53B, 0x1D53E, 0x1D540, 0x1D544, + 0x1D546, 0x1D546, 0x1D54A, 0x1D550, 0x1D552, 0x1D6A3, 0x1D6A8, 0x1D7C9, + 0x20000, 0x2A6D6, 0x2F800, 0x2FA1D, 0xF0000, 0xFFFFD, 0x100000, 0x10FFFD}; + BSON_END_DECLS diff --git a/src/mongoc/mongoc-scram.c b/src/mongoc/mongoc-scram.c index d51f485e..7fdff0e9 100644 --- a/src/mongoc/mongoc-scram.c +++ b/src/mongoc/mongoc-scram.c @@ -29,10 +29,93 @@ #include "common-b64-private.h" #include "mongoc-memcmp-private.h" +#include "common-thread-private.h" +#include + +typedef struct _mongoc_scram_cache_entry_t { + /* book keeping */ + bool taken; + /* pre-secrets */ + char hashed_password[MONGOC_SCRAM_HASH_MAX_SIZE]; + uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE]; + uint32_t iterations; + /* secrets */ + uint8_t client_key[MONGOC_SCRAM_HASH_MAX_SIZE]; + uint8_t server_key[MONGOC_SCRAM_HASH_MAX_SIZE]; + uint8_t salted_password[MONGOC_SCRAM_HASH_MAX_SIZE]; +} mongoc_scram_cache_entry_t; #define MONGOC_SCRAM_SERVER_KEY "Server Key" #define MONGOC_SCRAM_CLIENT_KEY "Client Key" +/* returns true if the first UTF-8 code point in `s` is valid. */ +bool +_mongoc_utf8_first_code_point_is_valid (const char *c, size_t length); + +/* returns whether a character is between two limits (inclusive). */ +bool +_mongoc_utf8_code_unit_in_range (const uint8_t c, + const uint8_t lower, + const uint8_t upper); + +/* returns whether a codepoint exists in the specified table. The table format + * is that the 2*n element is the lower bound and the 2*n + 1 is the upper bound + * (both inclusive). */ +bool +_mongoc_utf8_code_point_is_in_table (uint32_t code, + const uint32_t *table, + size_t size); + +/* returns the byte length of the UTF-8 code point. Returns -1 if `c` is not a + * valid UTF-8 code point. */ +ssize_t +_mongoc_utf8_code_point_length (uint32_t c); + +/* converts a Unicode code point to UTF-8 character. Returns how many bytes the + * character converted is. Returns -1 if the code point is invalid. + * char *out must be large enough to contain all of the code units written to + * it. */ +ssize_t +_mongoc_utf8_code_point_to_str (uint32_t c, char *out); + +static bson_shared_mutex_t g_scram_cache_rwlock; + +static bson_once_t init_cache_once_control = BSON_ONCE_INIT; +static bson_mutex_t clear_cache_lock; + +/* + * Cache lookups are a linear search through this table. This table is a + * constant size, which is small enough that lookup cost is insignificant. + * + * This can be refactored into a hashmap if the cache size needs to grow larger + * in the future, but a linear lookup is currently fast enough and is much + * simpler logic to reason about. + */ +static mongoc_scram_cache_entry_t g_scram_cache[MONGOC_SCRAM_CACHE_SIZE]; + +static void +_mongoc_scram_cache_clear (void) +{ + bson_mutex_lock (&clear_cache_lock); + memset (g_scram_cache, 0, sizeof (g_scram_cache)); + bson_mutex_unlock (&clear_cache_lock); +} + +static BSON_ONCE_FUN (_mongoc_scram_cache_init) +{ + bson_shared_mutex_init (&g_scram_cache_rwlock); + bson_mutex_init (&clear_cache_lock); + _mongoc_scram_cache_clear (); + + BSON_ONCE_RETURN; +} + +static void +_mongoc_scram_cache_init_once (void) +{ + bson_once (&init_cache_once_control, _mongoc_scram_cache_init); +} + static int _scram_hash_size (mongoc_scram_t *scram) { @@ -46,7 +129,7 @@ _scram_hash_size (mongoc_scram_t *scram) /* Copies the cache's secrets to scram */ static void -_mongoc_scram_cache_apply_secrets (mongoc_scram_cache_t *cache, +_mongoc_scram_cache_apply_secrets (mongoc_scram_cache_entry_t *cache, mongoc_scram_t *scram) { BSON_ASSERT (cache); @@ -60,82 +143,66 @@ _mongoc_scram_cache_apply_secrets (mongoc_scram_cache_t *cache, } -static mongoc_scram_cache_t * -_mongoc_scram_cache_copy (const mongoc_scram_cache_t *cache) -{ - mongoc_scram_cache_t *ret = NULL; - - if (cache) { - ret = (mongoc_scram_cache_t *) bson_malloc0 (sizeof (*ret)); - ret->hashed_password = bson_strdup (cache->hashed_password); - memcpy ( - ret->decoded_salt, cache->decoded_salt, sizeof (ret->decoded_salt)); - ret->iterations = cache->iterations; - memcpy (ret->client_key, cache->client_key, sizeof (ret->client_key)); - memcpy (ret->server_key, cache->server_key, sizeof (ret->server_key)); - memcpy (ret->salted_password, - cache->salted_password, - sizeof (ret->salted_password)); - } - - return ret; -} - -#ifdef MONGOC_ENABLE_ICU -#include -#include -#endif - - void -_mongoc_scram_cache_destroy (mongoc_scram_cache_t *cache) +_mongoc_scram_cache_destroy (mongoc_scram_cache_entry_t *cache) { BSON_ASSERT (cache); - - if (cache->hashed_password) { - bson_zero_free (cache->hashed_password, strlen (cache->hashed_password)); - } - bson_free (cache); } -/* Checks whether the cache contains scram's pre-secrets */ +/* + * Checks whether the cache contains scram's pre-secrets. + * Populate `cache` with the values found in the global cache if found. + */ static bool -_mongoc_scram_cache_has_presecrets (mongoc_scram_cache_t *cache, - mongoc_scram_t *scram) +_mongoc_scram_cache_has_presecrets (mongoc_scram_cache_entry_t *cache /* out */, + const mongoc_scram_t *scram) { - BSON_ASSERT (cache); - BSON_ASSERT (scram); - - return cache->hashed_password && scram->hashed_password && - !strcmp (cache->hashed_password, scram->hashed_password) && - cache->iterations == scram->iterations && - !memcmp (cache->decoded_salt, - scram->decoded_salt, - sizeof (cache->decoded_salt)); -} - + bool cache_hit = false; -mongoc_scram_cache_t * -_mongoc_scram_get_cache (mongoc_scram_t *scram) -{ - BSON_ASSERT (scram); - - return _mongoc_scram_cache_copy (scram->cache); -} - - -void -_mongoc_scram_set_cache (mongoc_scram_t *scram, mongoc_scram_cache_t *cache) -{ + BSON_ASSERT (cache); BSON_ASSERT (scram); - if (scram->cache) { - _mongoc_scram_cache_destroy (scram->cache); + _mongoc_scram_cache_init_once (); + + /* + * - Take a read lock + * - Search through g_scram_cache if the hashed_password, decoded_salt, and + * iterations match an entry. + * - If so, then return true + * - Otherwise return false + */ + bson_shared_mutex_lock_shared (&g_scram_cache_rwlock); + + for (size_t i = 0; i < MONGOC_SCRAM_CACHE_SIZE; i++) { + if (g_scram_cache[i].taken) { + mongoc_scram_cache_entry_t *cache_entry = &g_scram_cache[i]; + cache_hit = + !strcmp (cache_entry->hashed_password, scram->hashed_password) && + cache_entry->iterations == scram->iterations && + !memcmp (cache_entry->decoded_salt, + scram->decoded_salt, + sizeof (cache_entry->decoded_salt)); + if (cache_hit) { + /* copy the found cache items into the 'cache' output parameter */ + memcpy (cache->client_key, + cache_entry->client_key, + sizeof (cache->client_key)); + memcpy (cache->server_key, + cache_entry->server_key, + sizeof (cache->server_key)); + memcpy (cache->salted_password, + cache_entry->salted_password, + sizeof (cache->salted_password)); + goto done; + } + } } - scram->cache = _mongoc_scram_cache_copy (cache); +done: + bson_shared_mutex_unlock_shared (&g_scram_cache_rwlock); + return cache_hit; } @@ -184,44 +251,85 @@ _mongoc_scram_destroy (mongoc_scram_t *scram) bson_zero_free (scram->pass, strlen (scram->pass)); } - if (scram->hashed_password) { - bson_zero_free (scram->hashed_password, strlen (scram->hashed_password)); - } + memset (scram->hashed_password, 0, sizeof (scram->hashed_password)); bson_free (scram->auth_message); - if (scram->cache) { - _mongoc_scram_cache_destroy (scram->cache); - } - memset (scram, 0, sizeof *scram); } - -/* Updates the cache with scram's last-used pre-secrets and secrets */ static void -_mongoc_scram_update_cache (mongoc_scram_t *scram) +_mongoc_scram_cache_insert (const mongoc_scram_t *scram) { - mongoc_scram_cache_t *cache; + bson_shared_mutex_lock (&g_scram_cache_rwlock); + +again: + for (size_t i = 0; i < MONGOC_SCRAM_CACHE_SIZE; i++) { + mongoc_scram_cache_entry_t *cache_entry = &g_scram_cache[i]; + bool already_exists = + !strcmp (cache_entry->hashed_password, scram->hashed_password) && + cache_entry->iterations == scram->iterations && + !memcmp (cache_entry->decoded_salt, + scram->decoded_salt, + sizeof (cache_entry->decoded_salt)) && + !memcmp (cache_entry->client_key, + scram->client_key, + sizeof (cache_entry->client_key)) && + !memcmp (cache_entry->server_key, + scram->server_key, + sizeof (cache_entry->server_key)) && + !memcmp (cache_entry->salted_password, + scram->salted_password, + sizeof (cache_entry->salted_password)); + + if (already_exists) { + /* cache entry already populated between read and write lock + * acquisition, skipping */ + break; + } - BSON_ASSERT (scram); + if (!cache_entry->taken) { + /* found an empty slot */ + memcpy (cache_entry->client_key, + scram->client_key, + sizeof (cache_entry->client_key)); + memcpy (cache_entry->server_key, + scram->server_key, + sizeof (cache_entry->server_key)); + memcpy (cache_entry->salted_password, + scram->salted_password, + sizeof (cache_entry->salted_password)); + memcpy (cache_entry->decoded_salt, + scram->decoded_salt, + sizeof (cache_entry->decoded_salt)); + memcpy (cache_entry->hashed_password, + scram->hashed_password, + sizeof (cache_entry->hashed_password)); + cache_entry->iterations = scram->iterations; + cache_entry->taken = true; + break; + } - if (scram->cache) { - _mongoc_scram_cache_destroy (scram->cache); + /* if cache is full, then invalidate the cache and insert again */ + if (i == (MONGOC_SCRAM_CACHE_SIZE - 1)) { + _mongoc_scram_cache_clear (); + goto again; + } } - cache = (mongoc_scram_cache_t *) bson_malloc0 (sizeof (*cache)); - cache->hashed_password = bson_strdup (scram->hashed_password); - memcpy ( - cache->decoded_salt, scram->decoded_salt, sizeof (cache->decoded_salt)); - cache->iterations = scram->iterations; - memcpy (cache->client_key, scram->client_key, sizeof (cache->client_key)); - memcpy (cache->server_key, scram->server_key, sizeof (cache->server_key)); - memcpy (cache->salted_password, - scram->salted_password, - sizeof (cache->salted_password)); + bson_shared_mutex_unlock (&g_scram_cache_rwlock); +} - scram->cache = cache; +/* Updates the cache with scram's last-used pre-secrets and secrets */ +static void +_mongoc_scram_update_cache (const mongoc_scram_t *scram) +{ + mongoc_scram_cache_entry_t cache; + bool found = _mongoc_scram_cache_has_presecrets (&cache, scram); + if (!found) { + /* cache miss, insert this as a new cache entry */ + _mongoc_scram_cache_insert (scram); + } } @@ -409,8 +517,6 @@ _mongoc_scram_salt_password (mongoc_scram_t *scram, uint8_t intermediate_digest[MONGOC_SCRAM_HASH_MAX_SIZE]; uint8_t start_key[MONGOC_SCRAM_HASH_MAX_SIZE]; - int i; - int k; uint8_t *output = scram->salted_password; memcpy (start_key, salt, salt_len); @@ -431,15 +537,17 @@ _mongoc_scram_salt_password (mongoc_scram_t *scram, /* intermediateDigest contains Ui and output contains the accumulated XOR:ed * result */ - for (i = 2; i <= iterations; i++) { + for (uint32_t i = 2u; i <= iterations; i++) { + const int hash_size = _scram_hash_size (scram); + mongoc_crypto_hmac (&scram->crypto, password, password_len, intermediate_digest, - _scram_hash_size (scram), + hash_size, intermediate_digest); - for (k = 0; k < _scram_hash_size (scram); k++) { + for (int k = 0; k < hash_size; k++) { output[k] ^= intermediate_digest[k]; } } @@ -532,7 +640,7 @@ _mongoc_scram_step2 (mongoc_scram_t *scram, const uint8_t *next_comma; char *tmp; - char *hashed_password; + char *hashed_password = NULL; uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE] = {0}; int32_t decoded_salt_len; @@ -559,8 +667,7 @@ _mongoc_scram_step2 (mongoc_scram_t *scram, /* Auth spec for SCRAM-SHA-256: "Passwords MUST be prepared with SASLprep, * per RFC 5802. Passwords are used directly for key derivation; they * MUST NOT be digested as they are in SCRAM-SHA-1." */ - hashed_password = - _mongoc_sasl_prep (scram->pass, (int) strlen (scram->pass), error); + hashed_password = _mongoc_sasl_prep (scram->pass, error); if (!hashed_password) { goto FAIL; } @@ -669,7 +776,7 @@ _mongoc_scram_step2 (mongoc_scram_t *scram, } /* verify our nonce */ - if (val_r_len < scram->encoded_nonce_len || + if (bson_cmp_less_us (val_r_len, scram->encoded_nonce_len) || mongoc_memcmp (val_r, scram->encoded_nonce, scram->encoded_nonce_len)) { bson_set_error ( error, @@ -755,13 +862,18 @@ _mongoc_scram_step2 (mongoc_scram_t *scram, } /* Save the presecrets for caching */ - scram->hashed_password = bson_strdup (hashed_password); + if (hashed_password) { + bson_strncpy (scram->hashed_password, + hashed_password, + sizeof (scram->hashed_password)); + } + scram->iterations = iterations; memcpy (scram->decoded_salt, decoded_salt, sizeof (scram->decoded_salt)); - if (scram->cache && - _mongoc_scram_cache_has_presecrets (scram->cache, scram)) { - _mongoc_scram_cache_apply_secrets (scram->cache, scram); + mongoc_scram_cache_entry_t cache; + if (_mongoc_scram_cache_has_presecrets (&cache, scram)) { + _mongoc_scram_cache_apply_secrets (&cache, scram); } if (!*scram->salted_password) { @@ -820,12 +932,15 @@ _mongoc_scram_verify_server_signature (mongoc_scram_t *scram, uint8_t server_signature[MONGOC_SCRAM_HASH_MAX_SIZE]; if (!*scram->server_key) { + const size_t key_len = strlen (MONGOC_SCRAM_SERVER_KEY); + BSON_ASSERT (bson_in_range_unsigned (int, key_len)); + /* ServerKey := HMAC(SaltedPassword, "Server Key") */ mongoc_crypto_hmac (&scram->crypto, scram->salted_password, _scram_hash_size (scram), (uint8_t *) MONGOC_SCRAM_SERVER_KEY, - strlen (MONGOC_SCRAM_SERVER_KEY), + (int) key_len, scram->server_key); } @@ -1025,19 +1140,17 @@ _mongoc_sasl_prep_required (const char *str) return false; } -#ifdef MONGOC_ENABLE_ICU char * _mongoc_sasl_prep_impl (const char *name, const char *in_utf8, - int in_utf8_len, bson_error_t *err) { - /* The flow is in_utf8 -> in_utf16 -> SASLPrep -> out_utf16 -> out_utf8. */ - UChar *in_utf16, *out_utf16; - char *out_utf8; - int32_t in_utf16_len, out_utf16_len, out_utf8_len; - UErrorCode error_code = U_ZERO_ERROR; - UStringPrepProfile *prep; + BSON_ASSERT_PARAM (name); + BSON_ASSERT_PARAM (in_utf8); + + uint32_t *utf8_codepoints; + ssize_t num_chars; + uint8_t *out_utf8; #define SASL_PREP_ERR_RETURN(msg) \ do { \ @@ -1049,102 +1162,402 @@ _mongoc_sasl_prep_impl (const char *name, return NULL; \ } while (0) - /* 1. convert str to UTF-16. */ + /* 1. convert str to Unicode codepoints. */ /* preflight to get the destination length. */ - (void) u_strFromUTF8 ( - NULL, 0, &in_utf16_len, in_utf8, in_utf8_len, &error_code); - if (error_code != U_BUFFER_OVERFLOW_ERROR) { - SASL_PREP_ERR_RETURN ("could not calculate UTF-16 length of %s"); - } - - /* convert to UTF-16. */ - error_code = U_ZERO_ERROR; - in_utf16 = bson_malloc (sizeof (UChar) * - (in_utf16_len + 1)); /* add one for null byte. */ - (void) u_strFromUTF8 ( - in_utf16, in_utf16_len + 1, NULL, in_utf8, in_utf8_len, &error_code); - if (error_code) { - bson_free (in_utf16); - SASL_PREP_ERR_RETURN ("could not convert %s to UTF-16"); - } - - /* 2. perform SASLPrep. */ - prep = usprep_openByType (USPREP_RFC4013_SASLPREP, &error_code); - if (error_code) { - bson_free (in_utf16); - SASL_PREP_ERR_RETURN ("could not start SASLPrep for %s"); - } - /* preflight. */ - out_utf16_len = usprep_prepare ( - prep, in_utf16, in_utf16_len, NULL, 0, USPREP_DEFAULT, NULL, &error_code); - if (error_code != U_BUFFER_OVERFLOW_ERROR) { - bson_free (in_utf16); - usprep_close (prep); - SASL_PREP_ERR_RETURN ("could not calculate SASLPrep length of %s"); - } - - /* convert. */ - error_code = U_ZERO_ERROR; - out_utf16 = bson_malloc (sizeof (UChar) * (out_utf16_len + 1)); - (void) usprep_prepare (prep, - in_utf16, - in_utf16_len, - out_utf16, - out_utf16_len + 1, - USPREP_DEFAULT, - NULL, - &error_code); - if (error_code) { - bson_free (in_utf16); - bson_free (out_utf16); - usprep_close (prep); - SASL_PREP_ERR_RETURN ("could not execute SASLPrep for %s"); - } - bson_free (in_utf16); - usprep_close (prep); - - /* 3. convert back to UTF-8. */ - /* preflight. */ - (void) u_strToUTF8 ( - NULL, 0, &out_utf8_len, out_utf16, out_utf16_len, &error_code); - if (error_code != U_BUFFER_OVERFLOW_ERROR) { - bson_free (out_utf16); + num_chars = _mongoc_utf8_string_length (in_utf8); + if (num_chars == -1) { SASL_PREP_ERR_RETURN ("could not calculate UTF-8 length of %s"); } - /* convert. */ - error_code = U_ZERO_ERROR; - out_utf8 = (char *) bson_malloc ( - sizeof (char) * (out_utf8_len + 1)); /* add one for null byte. */ - (void) u_strToUTF8 ( - out_utf8, out_utf8_len + 1, NULL, out_utf16, out_utf16_len, &error_code); - if (error_code) { + /* convert to unicode. */ + utf8_codepoints = bson_malloc ( + sizeof (uint32_t) * (num_chars + 1)); /* add one for trailing 0 value. */ + const char *c = in_utf8; + + for (size_t i = 0; i < num_chars; ++i) { + const size_t utf8_char_length = _mongoc_utf8_char_length (c); + utf8_codepoints[i] = + _mongoc_utf8_get_first_code_point (c, utf8_char_length); + + c += utf8_char_length; + } + utf8_codepoints[num_chars] = '\0'; + + /* 2. perform SASLPREP */ + + // the steps below come directly from RFC 3454: 2. Preparation Overview. + + // a. Map - For each character in the input, check if it has a mapping (using + // the tables) and, if so, replace it with its mapping. + + // because we will have to map some characters to nothing, we'll use two + // pointers: one for reading the original characters (i) and one for writing + // the new characters (curr). i will always be >= curr. + size_t curr = 0; + for (size_t i = 0; i < num_chars; ++i) { + if (_mongoc_utf8_code_point_is_in_table ( + utf8_codepoints[i], + non_ascii_space_character_ranges, + sizeof (non_ascii_space_character_ranges) / sizeof (uint32_t))) + utf8_codepoints[curr++] = 0x0020; + else if (_mongoc_utf8_code_point_is_in_table ( + utf8_codepoints[i], + commonly_mapped_to_nothing_ranges, + sizeof (commonly_mapped_to_nothing_ranges) / + sizeof (uint32_t))) { + // effectively skip over the character because we don't increment curr. + } else + utf8_codepoints[curr++] = utf8_codepoints[i]; + } + utf8_codepoints[curr] = '\0'; + num_chars = curr; + + + // b. Normalize - normalize the result of step `a` using Unicode + // normalization. + + // this is an optional step for stringprep, but Unicode normalization with + // form KC is required for SASLPrep. + + // in order to do this, we must first convert back to UTF-8. + + // preflight for length + size_t utf8_pre_norm_len = 0; + for (size_t i = 0; i < num_chars; ++i) { + const ssize_t len = _mongoc_utf8_code_point_length (utf8_codepoints[i]); + if (len == -1) { + bson_free (utf8_codepoints); + SASL_PREP_ERR_RETURN ("invalid Unicode code point in %s"); + } else { + utf8_pre_norm_len += len; + } + } + char *utf8_pre_norm = + (char *) bson_malloc (sizeof (char) * (utf8_pre_norm_len + 1)); + + char *loc = utf8_pre_norm; + for (size_t i = 0; i < num_chars; ++i) { + const ssize_t utf8_char_length = + _mongoc_utf8_code_point_to_str (utf8_codepoints[i], loc); + if (utf8_char_length == -1) { + bson_free (utf8_pre_norm); + bson_free (utf8_codepoints); + SASL_PREP_ERR_RETURN ("invalid Unicode code point in %s"); + } + loc += utf8_char_length; + } + *loc = '\0'; + + out_utf8 = (uint8_t *) utf8proc_NFKC ((utf8proc_uint8_t *) utf8_pre_norm); + + // the last two steps are both checks for characters that should not be + // allowed. Because the normalization step is guarenteed to not create any + // characters that will cause an error, we will use the utf8_codepoints + // codepoints to check (pre-normalization) as to avoid converting back and + // forth from UTF-8 to unicode codepoints. + + // c. Prohibit -- Check for any characters + // that are not allowed in the output. If any are found, return an error. + + for (size_t i = 0; i < num_chars; ++i) { + if (_mongoc_utf8_code_point_is_in_table ( + utf8_codepoints[i], + prohibited_output_ranges, + sizeof (prohibited_output_ranges) / sizeof (uint32_t)) || + _mongoc_utf8_code_point_is_in_table ( + utf8_codepoints[i], + unassigned_codepoint_ranges, + sizeof (unassigned_codepoint_ranges) / sizeof (uint32_t))) { + bson_free (out_utf8); + bson_free (utf8_pre_norm); + bson_free (utf8_codepoints); + SASL_PREP_ERR_RETURN ("prohibited character included in %s"); + } + } + + // d. Check bidi -- Possibly check for right-to-left characters, and if + // any are found, make sure that the whole string satisfies the + // requirements for bidirectional strings. If the string does not + // satisfy the requirements for bidirectional strings, return an + // error. + + // note: bidi stands for directional (text). Most characters are displayed + // left to right but some are displayed right to left. The requirements are + // as follows: + // 1. If a string contains any RandALCat character, it can't contain an LCat + // character + // 2. If it contains an RandALCat character, there must be an RandALCat + // character at the beginning and the end of the string (does not have to be + // the same character) + bool contains_LCat = false; + bool contains_RandALCar = false; + + + for (size_t i = 0; i < num_chars; ++i) { + if (_mongoc_utf8_code_point_is_in_table (utf8_codepoints[i], + LCat_bidi_ranges, + sizeof (LCat_bidi_ranges) / + sizeof (uint32_t))) { + contains_LCat = true; + } + if (_mongoc_utf8_code_point_is_in_table (utf8_codepoints[i], + RandALCat_bidi_ranges, + sizeof (RandALCat_bidi_ranges) / + sizeof (uint32_t))) + contains_RandALCar = true; + } + + if ( + // requirement 1 + (contains_RandALCar && contains_LCat) || + // requirement 2 + (contains_RandALCar && + (!_mongoc_utf8_code_point_is_in_table (utf8_codepoints[0], + RandALCat_bidi_ranges, + sizeof (RandALCat_bidi_ranges) / + sizeof (uint32_t)) || + !_mongoc_utf8_code_point_is_in_table (utf8_codepoints[num_chars - 1], + RandALCat_bidi_ranges, + sizeof (RandALCat_bidi_ranges) / + sizeof (uint32_t))))) { bson_free (out_utf8); - bson_free (out_utf16); - SASL_PREP_ERR_RETURN ("could not convert %s back to UTF-8"); + bson_free (utf8_pre_norm); + bson_free (utf8_codepoints); + SASL_PREP_ERR_RETURN ("%s does not meet bidirectional requirements"); } - bson_free (out_utf16); - return out_utf8; + + bson_free (utf8_pre_norm); + bson_free (utf8_codepoints); + + return (char *) out_utf8; #undef SASL_PREP_ERR_RETURN } -#endif char * -_mongoc_sasl_prep (const char *in_utf8, int in_utf8_len, bson_error_t *err) +_mongoc_sasl_prep (const char *in_utf8, bson_error_t *err) { - BSON_UNUSED (in_utf8_len); - -#ifdef MONGOC_ENABLE_ICU - return _mongoc_sasl_prep_impl ("password", in_utf8, in_utf8_len, err); -#else if (_mongoc_sasl_prep_required (in_utf8)) { - bson_set_error (err, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: ICU required to SASLPrep password"); - return NULL; + return _mongoc_sasl_prep_impl ("password", in_utf8, err); } return bson_strdup (in_utf8); -#endif } + +size_t +_mongoc_utf8_char_length (const char *s) +{ + BSON_ASSERT_PARAM (s); + + uint8_t *c = (uint8_t *) s; + // UTF-8 characters are either 1, 2, 3, or 4 bytes and the character length + // can be determined by the first byte + if ((*c & UINT8_C (0x80)) == 0) + return 1u; + else if ((*c & UINT8_C (0xe0)) == UINT8_C (0xc0)) + return 2u; + else if ((*c & UINT8_C (0xf0)) == UINT8_C (0xe0)) + return 3u; + else if ((*c & UINT8_C (0xf8)) == UINT8_C (0xf0)) + return 4u; + else + return 1u; +} + +ssize_t +_mongoc_utf8_string_length (const char *s) +{ + BSON_ASSERT_PARAM (s); + + const uint8_t *c = (uint8_t *) s; + + ssize_t str_length = 0; + + while (*c) { + const size_t utf8_char_length = _mongoc_utf8_char_length ((char *) c); + + if (!_mongoc_utf8_first_code_point_is_valid ((char *) c, + utf8_char_length)) + return -1; + + str_length++; + c += utf8_char_length; + } + + return str_length; +} + + +bool +_mongoc_utf8_first_code_point_is_valid (const char *c, size_t length) +{ + BSON_ASSERT_PARAM (c); + + uint8_t *temp_c = (uint8_t *) c; + // Referenced table here: + // https://lemire.me/blog/2018/05/09/how-quickly-can-you-check-that-a-string-is-valid-unicode-utf-8/ + switch (length) { + case 1: + return _mongoc_utf8_code_unit_in_range ( + temp_c[0], UINT8_C (0x00), UINT8_C (0x7F)); + case 2: + return _mongoc_utf8_code_unit_in_range ( + temp_c[0], UINT8_C (0xC2), UINT8_C (0xDF)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[1], UINT8_C (0x80), UINT8_C (0xBF)); + case 3: + // Four options, separated by || + return (_mongoc_utf8_code_unit_in_range ( + temp_c[0], UINT8_C (0xE0), UINT8_C (0xE0)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[1], UINT8_C (0xA0), UINT8_C (0xBF)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[2], UINT8_C (0x80), UINT8_C (0xBF))) || + (_mongoc_utf8_code_unit_in_range ( + temp_c[0], UINT8_C (0xE1), UINT8_C (0xEC)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[1], UINT8_C (0x80), UINT8_C (0xBF)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[2], UINT8_C (0x80), UINT8_C (0xBF))) || + (_mongoc_utf8_code_unit_in_range ( + temp_c[0], UINT8_C (0xED), UINT8_C (0xED)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[1], UINT8_C (0x80), UINT8_C (0x9F)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[2], UINT8_C (0x80), UINT8_C (0xBF))) || + (_mongoc_utf8_code_unit_in_range ( + temp_c[0], UINT8_C (0xEE), UINT8_C (0xEF)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[1], UINT8_C (0x80), UINT8_C (0xBF)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[2], UINT8_C (0x80), UINT8_C (0xBF))); + case 4: + // Three options, separated by || + return (_mongoc_utf8_code_unit_in_range ( + temp_c[0], UINT8_C (0xF0), UINT8_C (0xF0)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[1], UINT8_C (0x90), UINT8_C (0xBF)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[2], UINT8_C (0x80), UINT8_C (0xBF)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[3], UINT8_C (0x80), UINT8_C (0xBF))) || + (_mongoc_utf8_code_unit_in_range ( + temp_c[0], UINT8_C (0xF1), UINT8_C (0xF3)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[1], UINT8_C (0x80), UINT8_C (0xBF)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[2], UINT8_C (0x80), UINT8_C (0xBF)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[3], UINT8_C (0x80), UINT8_C (0xBF))) || + (_mongoc_utf8_code_unit_in_range ( + temp_c[0], UINT8_C (0xF4), UINT8_C (0xF4)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[1], UINT8_C (0x80), UINT8_C (0x8F)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[2], UINT8_C (0x80), UINT8_C (0xBF)) && + _mongoc_utf8_code_unit_in_range ( + temp_c[3], UINT8_C (0x80), UINT8_C (0xBF))); + default: + return true; + } +} + + +bool +_mongoc_utf8_code_unit_in_range (const uint8_t c, + const uint8_t lower, + const uint8_t upper) +{ + return (c >= lower && c <= upper); +} + +bool +_mongoc_utf8_code_point_is_in_table (uint32_t code, + const uint32_t *table, + size_t size) +{ + BSON_ASSERT_PARAM (table); + + // all tables have size / 2 ranges + for (size_t i = 0; i < size; i += 2) { + if (code >= table[i] && code <= table[i + 1]) + return true; + } + + return false; +} + +uint32_t +_mongoc_utf8_get_first_code_point (const char *c, size_t length) +{ + BSON_ASSERT_PARAM (c); + + uint8_t *temp_c = (uint8_t *) c; + switch (length) { + case 1: + return (uint32_t) temp_c[0]; + case 2: + return (uint32_t) (((temp_c[0] & UINT8_C (0x1f)) << 6) | + (temp_c[1] & UINT8_C (0x3f))); + case 3: + return (uint32_t) (((temp_c[0] & UINT8_C (0x0f)) << 12) | + ((temp_c[1] & UINT8_C (0x3f)) << 6) | + (temp_c[2] & UINT8_C (0x3f))); + case 4: + return (uint32_t) (((temp_c[0] & UINT8_C (0x07)) << 18) | + ((temp_c[1] & UINT8_C (0x3f)) << 12) | + ((temp_c[2] & UINT8_C (0x3f)) << 6) | + (temp_c[3] & UINT8_C (0x3f))); + default: + return 0; + } +} + +ssize_t +_mongoc_utf8_code_point_to_str (uint32_t c, char *out) +{ + BSON_ASSERT_PARAM (out); + + uint8_t *ptr = (uint8_t *) out; + + if (c <= UINT8_C (0x7F)) { + // Plain ASCII + ptr[0] = (uint8_t) c; + return 1; + } else if (c <= 0x07FF) { + // 2-byte unicode + ptr[0] = (uint8_t) (((c >> 6) & UINT8_C (0x1F)) | UINT8_C (0xC0)); + ptr[1] = (uint8_t) (((c >> 0) & UINT8_C (0x3F)) | UINT8_C (0x80)); + return 2; + } else if (c <= 0xFFFF) { + // 3-byte unicode + ptr[0] = (uint8_t) (((c >> 12) & UINT8_C (0x0F)) | UINT8_C (0xE0)); + ptr[1] = (uint8_t) (((c >> 6) & UINT8_C (0x3F)) | UINT8_C (0x80)); + ptr[2] = (uint8_t) ((c & UINT8_C (0x3F)) | UINT8_C (0x80)); + return 3; + } else if (c <= 0x10FFFF) { + // 4-byte unicode + ptr[0] = (uint8_t) (((c >> 18) & UINT8_C (0x07)) | UINT8_C (0xF0)); + ptr[1] = (uint8_t) (((c >> 12) & UINT8_C (0x3F)) | UINT8_C (0x80)); + ptr[2] = (uint8_t) (((c >> 6) & UINT8_C (0x3F)) | UINT8_C (0x80)); + ptr[3] = (uint8_t) ((c & UINT8_C (0x3F)) | UINT8_C (0x80)); + return 4; + } else { + return -1; + } +} + +ssize_t +_mongoc_utf8_code_point_length (uint32_t c) +{ + if (c <= UINT8_C (0x7F)) + return 1; + else if (c <= 0x07FF) + return 2; + else if (c <= 0xFFFF) + return 3; + else if (c <= 0x10FFFF) + return 4; + else + return -1; +} + #endif diff --git a/src/mongoc/mongoc-secure-channel-private.h b/src/mongoc/mongoc-secure-channel-private.h index a5b83a15..78e6b045 100644 --- a/src/mongoc/mongoc-secure-channel-private.h +++ b/src/mongoc/mongoc-secure-channel-private.h @@ -40,13 +40,21 @@ _mongoc_secure_channel_extract_subject (const char *filename, bool mongoc_secure_channel_setup_ca ( mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt); + bool mongoc_secure_channel_setup_crl ( mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt); -size_t + +ssize_t mongoc_secure_channel_read (mongoc_stream_tls_t *tls, void *data, size_t data_length); + +ssize_t +mongoc_secure_channel_write (mongoc_stream_tls_t *tls, + const void *data, + size_t data_length); + PCCERT_CONTEXT mongoc_secure_channel_setup_certificate ( mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt); @@ -85,7 +93,6 @@ mongoc_secure_channel_handshake_step_3 (mongoc_stream_tls_t *tls, char *hostname, bson_error_t *error); - BSON_END_DECLS diff --git a/src/mongoc/mongoc-secure-channel.c b/src/mongoc/mongoc-secure-channel.c index 51f213da..fd2007a5 100644 --- a/src/mongoc/mongoc-secure-channel.c +++ b/src/mongoc/mongoc-secure-channel.c @@ -467,23 +467,31 @@ mongoc_secure_channel_setup_crl ( return false; } -size_t +ssize_t mongoc_secure_channel_read (mongoc_stream_tls_t *tls, void *data, size_t data_length) { - ssize_t length; + BSON_ASSERT_PARAM (tls); + + if (BSON_UNLIKELY (!bson_in_range_signed (int32_t, tls->timeout_msec))) { + // CDRIVER-4589 + MONGOC_ERROR ("timeout_msec value %" PRId64 + " exceeds supported 32-bit range", + tls->timeout_msec); + return -1; + } errno = 0; - TRACE ("Wanting to read: %zu, timeout is %" PRId32, + TRACE ("Wanting to read: %zu, timeout is %" PRIu64, data_length, tls->timeout_msec); /* 4th argument is minimum bytes, while the data_length is the * size of the buffer. We are totally fine with just one TLS record (few *bytes) **/ - length = mongoc_stream_read ( - tls->base_stream, data, data_length, 0, tls->timeout_msec); + const ssize_t length = mongoc_stream_read ( + tls->base_stream, data, data_length, 0, (int32_t) tls->timeout_msec); TRACE ("Got %zd", length); @@ -494,20 +502,29 @@ mongoc_secure_channel_read (mongoc_stream_tls_t *tls, return 0; } -size_t +ssize_t mongoc_secure_channel_write (mongoc_stream_tls_t *tls, const void *data, size_t data_length) { - ssize_t length; + BSON_ASSERT_PARAM (tls); + + if (BSON_UNLIKELY (!bson_in_range_signed (int32_t, tls->timeout_msec))) { + // CDRIVER-4589 + MONGOC_ERROR ("timeout_msec value %" PRId64 + " exceeds supported 32-bit range", + tls->timeout_msec); + return -1; + } errno = 0; - TRACE ("Wanting to write: %zd", data_length); - length = mongoc_stream_write ( - tls->base_stream, (void *) data, data_length, tls->timeout_msec); + TRACE ("Wanting to write: %zu", data_length); + const ssize_t length = mongoc_stream_write (tls->base_stream, + (void *) data, + data_length, + (int32_t) tls->timeout_msec); TRACE ("Wrote: %zd", length); - return length; } @@ -739,7 +756,7 @@ mongoc_secure_channel_handshake_step_2 (mongoc_stream_tls_t *tls, _mongoc_secure_channel_init_sec_buffer ( &inbuf[0], SECBUFFER_TOKEN, - malloc (secure_channel->encdata_offset), + bson_malloc (secure_channel->encdata_offset), (unsigned long) (secure_channel->encdata_offset & (size_t) 0xFFFFFFFFUL)); _mongoc_secure_channel_init_sec_buffer ( @@ -785,7 +802,7 @@ mongoc_secure_channel_handshake_step_2 (mongoc_stream_tls_t *tls, &secure_channel->ctxt->time_stamp); /* free buffer for received handshake data */ - free (inbuf[0].pvBuffer); + bson_free (inbuf[0].pvBuffer); /* check if the handshake was incomplete */ if (sspi_status == SEC_E_INCOMPLETE_MESSAGE) { diff --git a/src/mongoc/mongoc-secure-transport.c b/src/mongoc/mongoc-secure-transport.c index af41a1d7..97437e0d 100644 --- a/src/mongoc/mongoc-secure-transport.c +++ b/src/mongoc/mongoc-secure-transport.c @@ -395,7 +395,7 @@ mongoc_secure_transport_setup_certificate ( TRACE ("Setting client certificate %s", success ? "succeeded" : "failed"); CFRelease (items); - return true; + return success; } bool @@ -447,7 +447,7 @@ mongoc_secure_transport_setup_ca ( TRACE ("Setting certificate authority %s (%s)", success ? "succeeded" : "failed", opt->ca_file); - return true; + return success; } OSStatus diff --git a/src/mongoc/mongoc-server-description-private.h b/src/mongoc/mongoc-server-description-private.h index 27a9e52a..58cfbb65 100644 --- a/src/mongoc/mongoc-server-description-private.h +++ b/src/mongoc/mongoc-server-description-private.h @@ -241,10 +241,4 @@ bool mongoc_server_description_has_service_id ( const mongoc_server_description_t *description); -/* mongoc_global_mock_service_id is only used for testing. The test runner sets - * this to true when testing against a load balanced deployment to mock the - * presence of a serviceId field in the "hello" response. The purpose of this is - * further described in the Load Balancer test README. */ -extern bool mongoc_global_mock_service_id; - #endif diff --git a/src/mongoc/mongoc-server-description.c b/src/mongoc/mongoc-server-description.c index 87558127..b1de91f9 100644 --- a/src/mongoc/mongoc-server-description.c +++ b/src/mongoc/mongoc-server-description.c @@ -25,6 +25,8 @@ #include "mongoc-util-private.h" #include "mongoc-compression-private.h" +#include + #include #define ALPHA 0.2 @@ -33,8 +35,6 @@ static bson_oid_t kObjectIdZero = {{0}}; const bson_oid_t kZeroServiceId = {{0}}; -bool mongoc_global_mock_service_id = false; - static bool _match_tag_set (const mongoc_server_description_t *sd, bson_iter_t *tag_set_iter); @@ -572,11 +572,8 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd, } bson_destroy (&sd->last_hello_response); - bson_init (&sd->last_hello_response); - bson_copy_to_excluding_noinit (hello_response, - &sd->last_hello_response, - "speculativeAuthenticate", - NULL); + bsonBuild (sd->last_hello_response, + insert (*hello_response, not(key ("speculativeAuthenticate")))); sd->has_hello_response = true; /* Only reinitialize the topology version if we have a hello response. @@ -601,33 +598,33 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd, * MUST treat this an authentication error." */ sd->error.domain = MONGOC_ERROR_CLIENT; sd->error.code = MONGOC_ERROR_CLIENT_AUTHENTICATE; - goto failure; + GOTO (authfailure); } } else if (strcmp ("isWritablePrimary", bson_iter_key (&iter)) == 0 || strcmp (HANDSHAKE_RESPONSE_LEGACY_HELLO, bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_BOOL (&iter)) - goto failure; + GOTO (typefailure); is_primary = bson_iter_bool (&iter); } else if (strcmp ("helloOk", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_BOOL (&iter)) - goto failure; + GOTO (typefailure); sd->hello_ok = bson_iter_bool (&iter); } else if (strcmp ("me", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_UTF8 (&iter)) - goto failure; + GOTO (typefailure); sd->me = bson_iter_utf8 (&iter, NULL); } else if (strcmp ("maxMessageSizeBytes", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_INT32 (&iter)) - goto failure; + GOTO (typefailure); sd->max_msg_size = bson_iter_int32 (&iter); } else if (strcmp ("maxBsonObjectSize", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_INT32 (&iter)) - goto failure; + GOTO (typefailure); sd->max_bson_obj_size = bson_iter_int32 (&iter); } else if (strcmp ("maxWriteBatchSize", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_INT32 (&iter)) - goto failure; + GOTO (typefailure); sd->max_write_batch_size = bson_iter_int32 (&iter); } else if (strcmp ("logicalSessionTimeoutMinutes", bson_iter_key (&iter)) == 0) { @@ -637,72 +634,72 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd, /* this arises executing standard JSON tests */ sd->session_timeout_minutes = MONGOC_NO_SESSIONS; } else { - goto failure; + GOTO (typefailure); } } else if (strcmp ("minWireVersion", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_INT32 (&iter)) - goto failure; + GOTO (typefailure); sd->min_wire_version = bson_iter_int32 (&iter); } else if (strcmp ("maxWireVersion", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_INT32 (&iter)) - goto failure; + GOTO (typefailure); sd->max_wire_version = bson_iter_int32 (&iter); } else if (strcmp ("msg", bson_iter_key (&iter)) == 0) { const char *msg; if (!BSON_ITER_HOLDS_UTF8 (&iter)) - goto failure; + GOTO (typefailure); msg = bson_iter_utf8 (&iter, NULL); if (msg && 0 == strcmp (msg, "isdbgrid")) { is_shard = true; } } else if (strcmp ("setName", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_UTF8 (&iter)) - goto failure; + GOTO (typefailure); sd->set_name = bson_iter_utf8 (&iter, NULL); } else if (strcmp ("setVersion", bson_iter_key (&iter)) == 0) { mongoc_server_description_set_set_version (sd, bson_iter_as_int64 (&iter)); } else if (strcmp ("electionId", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_OID (&iter)) - goto failure; + GOTO (typefailure); mongoc_server_description_set_election_id (sd, bson_iter_oid (&iter)); } else if (strcmp ("secondary", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_BOOL (&iter)) - goto failure; + GOTO (typefailure); is_secondary = bson_iter_bool (&iter); } else if (strcmp ("hosts", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_ARRAY (&iter)) - goto failure; + GOTO (typefailure); bson_iter_array (&iter, &len, &bytes); bson_destroy (&sd->hosts); BSON_ASSERT (bson_init_static (&sd->hosts, bytes, len)); } else if (strcmp ("passives", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_ARRAY (&iter)) - goto failure; + GOTO (typefailure); bson_iter_array (&iter, &len, &bytes); bson_destroy (&sd->passives); BSON_ASSERT (bson_init_static (&sd->passives, bytes, len)); } else if (strcmp ("arbiters", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_ARRAY (&iter)) - goto failure; + GOTO (typefailure); bson_iter_array (&iter, &len, &bytes); bson_destroy (&sd->arbiters); BSON_ASSERT (bson_init_static (&sd->arbiters, bytes, len)); } else if (strcmp ("primary", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_UTF8 (&iter)) - goto failure; + GOTO (typefailure); sd->current_primary = bson_iter_utf8 (&iter, NULL); } else if (strcmp ("arbiterOnly", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_BOOL (&iter)) - goto failure; + GOTO (typefailure); is_arbiter = bson_iter_bool (&iter); } else if (strcmp ("isreplicaset", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_BOOL (&iter)) - goto failure; + GOTO (typefailure); is_replicaset = bson_iter_bool (&iter); } else if (strcmp ("tags", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) - goto failure; + GOTO (typefailure); bson_iter_document (&iter, &len, &bytes); bson_destroy (&sd->tags); BSON_ASSERT (bson_init_static (&sd->tags, bytes, len)); @@ -713,13 +710,13 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd, !bson_iter_recurse (&iter, &child) || !bson_iter_find (&child, "lastWriteDate") || !BSON_ITER_HOLDS_DATE_TIME (&child)) { - goto failure; + GOTO (typefailure); } sd->last_write_date_ms = bson_iter_date_time (&child); } else if (strcmp ("compression", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_ARRAY (&iter)) - goto failure; + GOTO (typefailure); bson_iter_array (&iter, &len, &bytes); bson_destroy (&sd->compressors); BSON_ASSERT (bson_init_static (&sd->compressors, bytes, len)); @@ -727,35 +724,26 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd, bson_t incoming_topology_version; if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { - goto failure; + GOTO (typefailure); } bson_iter_document (&iter, &len, &bytes); - bson_init_static (&incoming_topology_version, bytes, len); + BSON_ASSERT ( + bson_init_static (&incoming_topology_version, bytes, len)); mongoc_server_description_set_topology_version ( sd, &incoming_topology_version); bson_destroy (&incoming_topology_version); } else if (strcmp ("serviceId", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_OID (&iter)) - goto failure; + GOTO (typefailure); bson_oid_copy_unsafe (bson_iter_oid (&iter), &sd->service_id); } else if (strcmp ("connectionId", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_INT (&iter)) - goto failure; + if (!BSON_ITER_HOLDS_NUMBER (&iter)) + GOTO (typefailure); sd->server_connection_id = bson_iter_as_int64 (&iter); } } - - if (mongoc_global_mock_service_id) { - bson_iter_t pid_iter; - - if (bson_iter_init_find (&pid_iter, &sd->topology_version, "processId") && - BSON_ITER_HOLDS_OID (&pid_iter)) { - bson_oid_copy (bson_iter_oid (&pid_iter), &sd->service_id); - } - } - if (is_shard) { sd->type = MONGOC_SERVER_MONGOS; } else if (sd->set_name) { @@ -787,7 +775,14 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd, EXIT; -failure: +typefailure: + bson_set_error (&sd->error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_INVALID_TYPE, + "unexpected type %s for field %s in hello response", + _mongoc_bson_type_to_str (bson_iter_type (&iter)), + bson_iter_key (&iter)); +authfailure: sd->type = MONGOC_SERVER_UNKNOWN; sd->round_trip_time_msec = MONGOC_RTT_UNSET; diff --git a/src/mongoc/mongoc-server-monitor.c b/src/mongoc/mongoc-server-monitor.c index 9da9ad05..b0925d3d 100644 --- a/src/mongoc/mongoc-server-monitor.c +++ b/src/mongoc/mongoc-server-monitor.c @@ -17,9 +17,10 @@ #include "common-thread-private.h" #include "mongoc-server-monitor-private.h" +#include "mongoc/mcd-rpc.h" #include "mongoc/mongoc-client-private.h" #include "mongoc/mongoc-error-private.h" -#include "mongoc/mongoc-flags-private.h" +#include "mongoc/mongoc-handshake-private.h" #include "mongoc/mongoc-ssl-private.h" #include "mongoc/mongoc-stream-private.h" #include "mongoc/mongoc-topology-background-monitoring-private.h" @@ -65,9 +66,9 @@ struct _mongoc_server_monitor_t { /* Default time to sleep between hello checks (reduced when a scan is * requested) */ - uint64_t heartbeat_frequency_ms; + int64_t heartbeat_frequency_ms; /* The minimum time to sleep between hello checks. */ - uint64_t min_heartbeat_frequency_ms; + int64_t min_heartbeat_frequency_ms; int64_t connect_timeout_ms; bool use_tls; #ifdef MONGOC_ENABLE_SSL @@ -78,7 +79,7 @@ struct _mongoc_server_monitor_t { * stream. */ mongoc_stream_initiator_t initiator; void *initiator_context; - int64_t request_id; + int32_t request_id; mongoc_apm_callbacks_t apm_callbacks; void *apm_context; @@ -210,108 +211,146 @@ _server_monitor_append_cluster_time (mongoc_server_monitor_t *server_monitor, } mc_tpld_drop_ref (&td); } + +static int32_t +_int32_from_le (const void *data) +{ + BSON_ASSERT_PARAM (data); + return bson_iter_int32_unsafe (&(bson_iter_t){.raw = data}); +} + static bool _server_monitor_send_and_recv_hello_opmsg ( mongoc_server_monitor_t *server_monitor, - bson_t *cmd, + const bson_t *cmd, bson_t *reply, bson_error_t *error) { - mongoc_rpc_t rpc = {0}; - mongoc_array_t array_to_write; - mongoc_iovec_t *iovec; - int niovec; + bool ret = false; + mcd_rpc_message *const rpc = mcd_rpc_message_new (); mongoc_buffer_t buffer; - uint32_t reply_len; - bson_t temp_reply; - bool ret = false; + _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); + void *decompressed_data = NULL; + size_t decompressed_data_len = 0u; + + /* First, let's construct and send our OP_MSG: */ + { + int32_t message_length = 0; - /* First, let's construct and send our OPCODE_MSG: */ - rpc.header.msg_len = 0; - rpc.header.request_id = server_monitor->request_id++; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_MSG; - rpc.msg.flags = 0; - rpc.msg.n_sections = 1; - rpc.msg.sections[0].payload_type = 0; - rpc.msg.sections[0].payload.bson_document = bson_get_data (cmd); + message_length += mcd_rpc_header_set_message_length (rpc, 0); + message_length += + mcd_rpc_header_set_request_id (rpc, server_monitor->request_id++); + message_length += mcd_rpc_header_set_response_to (rpc, 0); + message_length += mcd_rpc_header_set_op_code (rpc, MONGOC_OP_CODE_MSG); - _mongoc_array_init (&array_to_write, sizeof (mongoc_iovec_t)); - _mongoc_rpc_gather (&rpc, &array_to_write); + mcd_rpc_op_msg_set_sections_count (rpc, 1u); - iovec = (mongoc_iovec_t *) array_to_write.data; - niovec = array_to_write.len; - _mongoc_rpc_swab_to_le (&rpc); + message_length += + mcd_rpc_op_msg_set_flag_bits (rpc, MONGOC_OP_MSG_FLAG_NONE); + message_length += mcd_rpc_op_msg_section_set_kind (rpc, 0u, 0); + message_length += + mcd_rpc_op_msg_section_set_body (rpc, 0u, bson_get_data (cmd)); + + mcd_rpc_message_set_length (rpc, message_length); + } + + size_t num_iovecs = 0u; + mongoc_iovec_t *const iovecs = mcd_rpc_message_to_iovecs (rpc, &num_iovecs); + BSON_ASSERT (iovecs); MONITOR_LOG (server_monitor, "sending with timeout %" PRId64, server_monitor->connect_timeout_ms); + mcd_rpc_message_egress (rpc); if (!_mongoc_stream_writev_full (server_monitor->stream, - iovec, - niovec, + iovecs, + num_iovecs, server_monitor->connect_timeout_ms, error)) { MONITOR_LOG_ERROR ( server_monitor, "failed to write polling hello: %s", error->message); - _mongoc_array_destroy (&array_to_write); - return false; + goto fail; } /* Done sending! Now, receive the reply: */ - - _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); - if (!_mongoc_buffer_append_from_stream (&buffer, server_monitor->stream, - 4, + sizeof (int32_t), server_monitor->connect_timeout_ms, error)) { goto fail; } - memcpy (&reply_len, buffer.data, 4); - reply_len = BSON_UINT32_FROM_LE (reply_len); + const int32_t message_length = _int32_from_le (buffer.data); + + // msgHeader consists of four int32 fields. + const int32_t message_header_length = 4u * sizeof (int32_t); + + if (message_length < message_header_length) { + bson_set_error (error, + MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "invalid reply from server: message length"); + goto fail; + } + + const size_t remaining_bytes = (size_t) message_length - sizeof (int32_t); if (!_mongoc_buffer_append_from_stream (&buffer, server_monitor->stream, - reply_len - buffer.len, + remaining_bytes, server_monitor->connect_timeout_ms, error)) { goto fail; } - if (!_mongoc_rpc_scatter (&rpc, buffer.data, buffer.len)) { + mcd_rpc_message_reset (rpc); + if (!mcd_rpc_message_from_data_in_place ( + rpc, buffer.data, buffer.len, NULL)) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid reply from server."); - + "invalid reply from server: malformed message"); goto fail; } - if (!_mongoc_rpc_decompress_if_necessary (&rpc, &buffer, error)) { + mcd_rpc_message_ingress (rpc); + + if (!mcd_rpc_message_decompress_if_necessary ( + rpc, &decompressed_data, &decompressed_data_len)) { + bson_set_error (error, + MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "invalid reply from server: decompression failure"); goto fail; } - _mongoc_rpc_swab_from_le (&rpc); - if (!_mongoc_rpc_get_first_document (&rpc, &temp_reply)) { + bson_t body; + if (!mcd_rpc_message_get_body (rpc, &body)) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid reply from server"); + "invalid reply from server: malformed body"); goto fail; } - bson_copy_to (&temp_reply, reply); + + bson_copy_to (&body, reply); + bson_destroy (&body); ret = true; + fail: if (!ret) { bson_init (reply); } - _mongoc_array_destroy (&array_to_write); + + bson_free (decompressed_data); _mongoc_buffer_destroy (&buffer); + bson_free (iovecs); + mcd_rpc_message_destroy (rpc); + return ret; } @@ -321,36 +360,43 @@ _server_monitor_send_and_recv_opquery (mongoc_server_monitor_t *server_monitor, bson_t *reply, bson_error_t *error) { - mongoc_rpc_t rpc; - mongoc_array_t array_to_write; - mongoc_iovec_t *iovec; - int niovec; - mongoc_buffer_t buffer; - uint32_t reply_len; - bson_t temp_reply; bool ret = false; - rpc.header.msg_len = 0; - rpc.header.request_id = server_monitor->request_id++; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_QUERY; - rpc.query.flags = MONGOC_QUERY_SECONDARY_OK; - rpc.query.collection = "admin.$cmd"; - rpc.query.skip = 0; - rpc.query.n_return = -1; - rpc.query.query = bson_get_data (cmd); - rpc.query.fields = NULL; - + mcd_rpc_message *const rpc = mcd_rpc_message_new (); + size_t num_iovecs = 0u; + mongoc_iovec_t *iovecs = NULL; + mongoc_buffer_t buffer; _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); - _mongoc_array_init (&array_to_write, sizeof (mongoc_iovec_t)); - _mongoc_rpc_gather (&rpc, &array_to_write); - iovec = (mongoc_iovec_t *) array_to_write.data; - niovec = array_to_write.len; - _mongoc_rpc_swab_to_le (&rpc); + void *decompressed_data = NULL; + size_t decompressed_data_len = 0u; + + { + int32_t message_length = 0; + + message_length += mcd_rpc_header_set_message_length (rpc, 0); + message_length += + mcd_rpc_header_set_request_id (rpc, server_monitor->request_id++); + message_length += mcd_rpc_header_set_response_to (rpc, 0); + message_length += mcd_rpc_header_set_op_code (rpc, MONGOC_OP_CODE_QUERY); + + message_length += + mcd_rpc_op_query_set_flags (rpc, MONGOC_OP_QUERY_FLAG_SECONDARY_OK); + message_length += + mcd_rpc_op_query_set_full_collection_name (rpc, "admin.$cmd"); + message_length += mcd_rpc_op_query_set_number_to_skip (rpc, 0); + message_length += mcd_rpc_op_query_set_number_to_return (rpc, -1); + message_length += mcd_rpc_op_query_set_query (rpc, bson_get_data (cmd)); + + mcd_rpc_message_set_length (rpc, message_length); + } + + iovecs = mcd_rpc_message_to_iovecs (rpc, &num_iovecs); + BSON_ASSERT (iovecs); + mcd_rpc_message_egress (rpc); if (!_mongoc_stream_writev_full (server_monitor->stream, - iovec, - niovec, + iovecs, + num_iovecs, server_monitor->connect_timeout_ms, error)) { goto fail; @@ -358,56 +404,102 @@ _server_monitor_send_and_recv_opquery (mongoc_server_monitor_t *server_monitor, if (!_mongoc_buffer_append_from_stream (&buffer, server_monitor->stream, - 4, + sizeof (int32_t), server_monitor->connect_timeout_ms, error)) { goto fail; } - memcpy (&reply_len, buffer.data, 4); - reply_len = BSON_UINT32_FROM_LE (reply_len); + const int32_t message_length = _int32_from_le (buffer.data); + + // msgHeader consists of four int32 fields. + const int32_t message_header_length = 4u * sizeof (int32_t); + + if (message_length < message_header_length) { + bson_set_error (error, + MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "invalid reply from server: message length"); + goto fail; + } + + const size_t remaining_bytes = (size_t) message_length - sizeof (int32_t); if (!_mongoc_buffer_append_from_stream (&buffer, server_monitor->stream, - reply_len - buffer.len, + remaining_bytes, server_monitor->connect_timeout_ms, error)) { goto fail; } - if (!_mongoc_rpc_scatter (&rpc, buffer.data, buffer.len)) { + mcd_rpc_message_reset (rpc); + if (!mcd_rpc_message_from_data_in_place ( + rpc, buffer.data, buffer.len, NULL)) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid reply from server."); - + "invalid reply from server: malformed message"); goto fail; } - if (!_mongoc_rpc_decompress_if_necessary (&rpc, &buffer, error)) { + mcd_rpc_message_ingress (rpc); + + if (!mcd_rpc_message_decompress_if_necessary ( + rpc, &decompressed_data, &decompressed_data_len)) { + bson_set_error (error, + MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "invalid reply from server: decompression failure"); goto fail; } - _mongoc_rpc_swab_from_le (&rpc); - if (!_mongoc_rpc_get_first_document (&rpc, &temp_reply)) { + bson_t body; + if (!mcd_rpc_message_get_body (rpc, &body)) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid reply from server"); + "invalid reply from server: malformed body"); goto fail; } - bson_copy_to (&temp_reply, reply); + + bson_copy_to (&body, reply); + bson_destroy (&body); ret = true; + fail: if (!ret) { bson_init (reply); } - _mongoc_array_destroy (&array_to_write); + + bson_free (decompressed_data); _mongoc_buffer_destroy (&buffer); + bson_free (iovecs); + mcd_rpc_message_destroy (rpc); + return ret; } +static bool +_server_monitor_send_and_recv (mongoc_server_monitor_t *server_monitor, + bson_t *cmd, + bson_t *reply, + bson_error_t *error) +{ + if (mongoc_topology_uses_server_api (server_monitor->topology) || + mongoc_topology_uses_loadbalanced (server_monitor->topology)) { + /* OP_MSG requires a "db" parameter: */ + bson_append_utf8 (cmd, "$db", 3, "admin", 5); + + return _server_monitor_send_and_recv_hello_opmsg ( + server_monitor, cmd, reply, error); + } else { + return _server_monitor_send_and_recv_opquery ( + server_monitor, cmd, reply, error); + } +} + static bool _server_monitor_polling_hello (mongoc_server_monitor_t *server_monitor, bool hello_ok, @@ -423,8 +515,10 @@ _server_monitor_polling_hello (mongoc_server_monitor_t *server_monitor, bson_copy_to (hello, &cmd); _server_monitor_append_cluster_time (server_monitor, &cmd); - ret = _server_monitor_send_and_recv_opquery ( + + ret = _server_monitor_send_and_recv ( server_monitor, &cmd, hello_response, error); + bson_destroy (&cmd); return ret; } @@ -434,43 +528,56 @@ _server_monitor_awaitable_hello_send (mongoc_server_monitor_t *server_monitor, bson_t *cmd, bson_error_t *error) { - mongoc_rpc_t rpc = {0}; - mongoc_array_t array_to_write; - mongoc_iovec_t *iovec; - int niovec; - - rpc.header.msg_len = 0; - rpc.header.request_id = server_monitor->request_id++; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_MSG; - rpc.msg.flags = MONGOC_MSG_EXHAUST_ALLOWED; - rpc.msg.n_sections = 1; - rpc.msg.sections[0].payload_type = 0; - rpc.msg.sections[0].payload.bson_document = bson_get_data (cmd); - - _mongoc_array_init (&array_to_write, sizeof (mongoc_iovec_t)); - _mongoc_rpc_gather (&rpc, &array_to_write); - - iovec = (mongoc_iovec_t *) array_to_write.data; - niovec = array_to_write.len; - _mongoc_rpc_swab_to_le (&rpc); + bool ret = false; + + mcd_rpc_message *const rpc = mcd_rpc_message_new (); + + { + int32_t message_length = 0; + + message_length += mcd_rpc_header_set_message_length (rpc, 0); + message_length += + mcd_rpc_header_set_request_id (rpc, server_monitor->request_id++); + message_length += mcd_rpc_header_set_response_to (rpc, 0); + message_length += mcd_rpc_header_set_op_code (rpc, MONGOC_OP_CODE_MSG); + + mcd_rpc_op_msg_set_sections_count (rpc, 1); + + message_length += + mcd_rpc_op_msg_set_flag_bits (rpc, MONGOC_OP_MSG_FLAG_EXHAUST_ALLOWED); + message_length += mcd_rpc_op_msg_section_set_kind (rpc, 0u, 0); + message_length += + mcd_rpc_op_msg_section_set_body (rpc, 0u, bson_get_data (cmd)); + + mcd_rpc_message_set_length (rpc, message_length); + } + + size_t num_iovecs; + mongoc_iovec_t *const iovecs = mcd_rpc_message_to_iovecs (rpc, &num_iovecs); + BSON_ASSERT (iovecs); MONITOR_LOG (server_monitor, "sending with timeout %" PRId64, server_monitor->connect_timeout_ms); + mcd_rpc_message_egress (rpc); if (!_mongoc_stream_writev_full (server_monitor->stream, - iovec, - niovec, + iovecs, + num_iovecs, server_monitor->connect_timeout_ms, error)) { MONITOR_LOG_ERROR ( server_monitor, "failed to write awaitable hello: %s", error->message); - _mongoc_array_destroy (&array_to_write); - return false; + goto done; } - _mongoc_array_destroy (&array_to_write); - return true; + + ret = true; + +done: + bson_free (iovecs); + mcd_rpc_message_destroy (rpc); + + return ret; } /* Poll the server monitor stream for reading. Allows cancellation. @@ -588,96 +695,121 @@ _server_monitor_awaitable_hello_recv (mongoc_server_monitor_t *server_monitor, bson_error_t *error) { bool ret = false; - mongoc_buffer_t buffer; - int32_t msg_len; - mongoc_rpc_t rpc; - bson_t reply_local; - int64_t expire_at_ms; - int64_t timeout_ms; - expire_at_ms = _now_ms () + server_monitor->heartbeat_frequency_ms + - server_monitor->connect_timeout_ms; + int64_t timeout_ms; + mcd_rpc_message *const rpc = mcd_rpc_message_new (); + mongoc_buffer_t buffer; _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); + void *decompressed_data = NULL; + size_t decompressed_data_len = 0u; + + const int64_t expire_at_ms = _now_ms () + + server_monitor->heartbeat_frequency_ms + + server_monitor->connect_timeout_ms; + if (!_server_monitor_poll_with_interrupt ( server_monitor, expire_at_ms, cancelled, error)) { GOTO (fail); } timeout_ms = _get_timeout_ms (expire_at_ms, error); - if (!timeout_ms) { + if (timeout_ms == 0) { GOTO (fail); } + MONITOR_LOG (server_monitor, "reading first 4 bytes with timeout: %" PRId64, timeout_ms); - if (!_mongoc_buffer_append_from_stream ( - &buffer, server_monitor->stream, 4, (int32_t) timeout_ms, error)) { + if (!_mongoc_buffer_append_from_stream (&buffer, + server_monitor->stream, + sizeof (int32_t), + (int32_t) timeout_ms, + error)) { GOTO (fail); } - BSON_ASSERT (buffer.len == 4); - memcpy (&msg_len, buffer.data, 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); + const int32_t message_length = _int32_from_le (buffer.data); + + // msgHeader consists of four int32 fields. + const int32_t message_header_length = 4u * sizeof (int32_t); - if ((msg_len < 16) || - (msg_len > server_monitor->description->max_msg_size)) { - bson_set_error ( - error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Message size %d is not within expected range 16-%d bytes", - msg_len, - server_monitor->description->max_msg_size); + if ((message_length < message_header_length) || + (message_length > server_monitor->description->max_msg_size)) { + bson_set_error (error, + MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "message size %" PRId32 + " is not within expected range 16-%" PRId32 " bytes", + message_length, + server_monitor->description->max_msg_size); GOTO (fail); } timeout_ms = _get_timeout_ms (expire_at_ms, error); - if (!timeout_ms) { + if (timeout_ms == 0) { GOTO (fail); } + + const size_t remaining_bytes = (size_t) message_length - sizeof (int32_t); + MONITOR_LOG (server_monitor, - "reading remaining %d bytes. Timeout %" PRId64, - (int) (msg_len - 4), + "reading remaining %zu bytes. Timeout %" PRId64, + remaining_bytes, timeout_ms); - if (!_mongoc_buffer_append_from_stream ( - &buffer, server_monitor->stream, msg_len - 4, timeout_ms, error)) { + if (!_mongoc_buffer_append_from_stream (&buffer, + server_monitor->stream, + remaining_bytes, + timeout_ms, + error)) { GOTO (fail); } - if (!_mongoc_rpc_scatter (&rpc, buffer.data, buffer.len)) { + if (!mcd_rpc_message_from_data_in_place ( + rpc, buffer.data, buffer.len, NULL)) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Malformed message from server"); + "malformed message from server"); GOTO (fail); } - if (!_mongoc_rpc_decompress_if_necessary (&rpc, &buffer, error)) { + mcd_rpc_message_ingress (rpc); + + if (!mcd_rpc_message_decompress_if_necessary ( + rpc, &decompressed_data, &decompressed_data_len)) { + bson_set_error (error, + MONGOC_ERROR_PROTOCOL, + MONGOC_ERROR_PROTOCOL_INVALID_REPLY, + "decompression failure"); GOTO (fail); } - _mongoc_rpc_swab_from_le (&rpc); - memcpy (&msg_len, rpc.msg.sections[0].payload.bson_document, 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - if (!bson_init_static ( - &reply_local, rpc.msg.sections[0].payload.bson_document, msg_len)) { + bson_t body; + if (!mcd_rpc_message_get_body (rpc, &body)) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Malformed BSON payload from server"); + "malformed BSON payload from server"); GOTO (fail); } - bson_copy_to (&reply_local, hello_response); - server_monitor->more_to_come = - (rpc.msg.flags & MONGOC_MSG_MORE_TO_COME) != 0; + bson_copy_to (&body, hello_response); + bson_destroy (&body); + + server_monitor->more_to_come = (mcd_rpc_op_msg_get_flag_bits (rpc) & + MONGOC_OP_MSG_FLAG_MORE_TO_COME) != 0; ret = true; + fail: if (!ret) { bson_init (hello_response); } + + bson_free (decompressed_data); _mongoc_buffer_destroy (&buffer); + mcd_rpc_message_destroy (rpc); + return ret; } @@ -705,7 +837,7 @@ _server_monitor_awaitable_hello (mongoc_server_monitor_t *server_monitor, _server_monitor_append_cluster_time (server_monitor, &cmd); bson_append_document ( &cmd, "topologyVersion", 15, &description->topology_version); - bson_append_int32 ( + bson_append_int64 ( &cmd, "maxAwaitTimeMS", 14, server_monitor->heartbeat_frequency_ms); bson_append_utf8 (&cmd, "$db", 3, "admin", 5); @@ -873,24 +1005,9 @@ _server_monitor_setup_connection (mongoc_server_monitor_t *server_monitor, _server_monitor_append_cluster_time (server_monitor, &cmd); bson_destroy (hello_response); - /* If the user has select a versioned API, we'll assume OPCODE_MSG; - otherwise, we'll use the legacy OPCODE_QUERY: */ - if (mongoc_topology_uses_server_api (server_monitor->topology)) { - /* OPCODE_MSG requires a "db" parameter: */ - bson_append_utf8 (&cmd, "$db", 3, "admin", 5); - - if (!_server_monitor_send_and_recv_hello_opmsg ( - server_monitor, &cmd, hello_response, error)) { - GOTO (fail); - } - } else { - if (!_server_monitor_send_and_recv_opquery ( - server_monitor, &cmd, hello_response, error)) { - GOTO (fail); - } - } + ret = _server_monitor_send_and_recv ( + server_monitor, &cmd, hello_response, error); - ret = true; fail: bson_destroy (&cmd); RETURN (ret); @@ -957,7 +1074,11 @@ _server_monitor_check_server ( GOTO (exit); } - if (!bson_empty (&previous_description->topology_version)) { + if (!bson_empty (&previous_description->topology_version) && + _mongoc_handshake_get ()->env == MONGOC_HANDSHAKE_ENV_NONE) { + // Use stream monitoring if: + // - Server supports stream monitoring (indicated by `topologyVersion`). + // - Application is not in an FaaS environment (e.g. AWS Lambda). awaited = true; _server_monitor_heartbeat_started (server_monitor, awaited); MONITOR_LOG (server_monitor, "awaitable hello"); @@ -1286,9 +1407,19 @@ mongoc_server_monitor_run (mongoc_server_monitor_t *server_monitor) bson_mutex_lock (&server_monitor->shared.mutex); if (server_monitor->shared.state == MONGOC_THREAD_OFF) { server_monitor->is_rtt = false; - server_monitor->shared.state = MONGOC_THREAD_RUNNING; - mcommon_thread_create ( + int ret = mcommon_thread_create ( &server_monitor->thread, _server_monitor_thread, server_monitor); + if (ret == 0) { + server_monitor->shared.state = MONGOC_THREAD_RUNNING; + } else { + char errmsg_buf[BSON_ERROR_BUFFER_SIZE]; + char *errmsg = bson_strerror_r (ret, errmsg_buf, sizeof errmsg_buf); + _server_monitor_log (server_monitor, + MONGOC_LOG_LEVEL_ERROR, + "Failed to start monitoring thread. This server " + "may not be selectable. Error: %s", + errmsg); + } } bson_mutex_unlock (&server_monitor->shared.mutex); } @@ -1299,9 +1430,19 @@ mongoc_server_monitor_run_as_rtt (mongoc_server_monitor_t *server_monitor) bson_mutex_lock (&server_monitor->shared.mutex); if (server_monitor->shared.state == MONGOC_THREAD_OFF) { server_monitor->is_rtt = true; - server_monitor->shared.state = MONGOC_THREAD_RUNNING; - mcommon_thread_create ( + int ret = mcommon_thread_create ( &server_monitor->thread, _server_monitor_rtt_thread, server_monitor); + if (ret == 0) { + server_monitor->shared.state = MONGOC_THREAD_RUNNING; + } else { + char errmsg_buf[BSON_ERROR_BUFFER_SIZE]; + char *errmsg = bson_strerror_r (ret, errmsg_buf, sizeof errmsg_buf); + _server_monitor_log ( + server_monitor, + MONGOC_LOG_LEVEL_ERROR, + "Failed to start Round-Trip Time monitoring thread. Error: %s", + errmsg); + } } bson_mutex_unlock (&server_monitor->shared.mutex); } diff --git a/src/mongoc/mongoc-server-stream-private.h b/src/mongoc/mongoc-server-stream-private.h index 29109dc0..0dfab757 100644 --- a/src/mongoc/mongoc-server-stream-private.h +++ b/src/mongoc/mongoc-server-stream-private.h @@ -31,12 +31,16 @@ BSON_BEGIN_DECLS typedef struct _mongoc_server_stream_t { mongoc_topology_description_type_t topology_type; - mongoc_server_description_t *sd; /* owned */ - bson_t cluster_time; /* owned */ - mongoc_stream_t *stream; /* borrowed */ - /** If the stream was created in a way that may have overwritten the user's - * readPreference, we need to know if server selection forced that change. */ + mongoc_server_description_t *sd; // owned + bson_t cluster_time; // owned + mongoc_stream_t *stream; // borrowed + // If the stream was created in a way that may have overwritten the user's + // readPreference, we need to know if server selection forced that change. bool must_use_primary; + // True if this server stream was acquired during a retry attempt triggered + // by a network error establishing an initial connection. Used to avoid + // further retry attempts. + bool retry_attempted; } mongoc_server_stream_t; diff --git a/src/mongoc/mongoc-server-stream.c b/src/mongoc/mongoc-server-stream.c index 99b01bfd..7c03ebd8 100644 --- a/src/mongoc/mongoc-server-stream.c +++ b/src/mongoc/mongoc-server-stream.c @@ -38,6 +38,7 @@ mongoc_server_stream_new (const mongoc_topology_description_t *td, server_stream->sd = sd; /* becomes owned */ server_stream->stream = stream; /* merely borrowed */ server_stream->must_use_primary = false; + server_stream->retry_attempted = false; return server_stream; } diff --git a/src/mongoc/mongoc-set-private.h b/src/mongoc/mongoc-set-private.h index 87c73f93..abef6409 100644 --- a/src/mongoc/mongoc-set-private.h +++ b/src/mongoc/mongoc-set-private.h @@ -64,20 +64,22 @@ mongoc_set_get_const (const mongoc_set_t *set, uint32_t id) } void * -mongoc_set_get_item (mongoc_set_t *set, int idx); +mongoc_set_get_item (mongoc_set_t *set, size_t idx); static BSON_INLINE const void * -mongoc_set_get_item_const (const mongoc_set_t *set, int idx) +mongoc_set_get_item_const (const mongoc_set_t *set, size_t idx) { return mongoc_set_get_item ((mongoc_set_t *) set, idx); } void * -mongoc_set_get_item_and_id (mongoc_set_t *set, int idx, uint32_t *id /* OUT */); +mongoc_set_get_item_and_id (mongoc_set_t *set, + size_t idx, + uint32_t *id /* OUT */); static BSON_INLINE const void * mongoc_set_get_item_and_id_const (const mongoc_set_t *set, - int idx, + size_t idx, uint32_t *id) { return mongoc_set_get_item_and_id ((mongoc_set_t *) set, idx, id); diff --git a/src/mongoc/mongoc-set.c b/src/mongoc/mongoc-set.c index 928fec86..df99d074 100644 --- a/src/mongoc/mongoc-set.c +++ b/src/mongoc/mongoc-set.c @@ -74,13 +74,9 @@ mongoc_set_add (mongoc_set_t *set, uint32_t id, void *item) void mongoc_set_rm (mongoc_set_t *set, uint32_t id) { - mongoc_set_item_t *ptr; - mongoc_set_item_t key; - int i; + const mongoc_set_item_t key = {.id = id}; - key.id = id; - - ptr = (mongoc_set_item_t *) bsearch ( + mongoc_set_item_t *const ptr = (mongoc_set_item_t *) bsearch ( &key, set->items, set->items_len, sizeof (key), mongoc_set_id_cmp); if (ptr) { @@ -88,12 +84,12 @@ mongoc_set_rm (mongoc_set_t *set, uint32_t id) set->dtor (ptr->item, set->dtor_ctx); } - i = ptr - set->items; + const size_t index = (size_t) (ptr - set->items); - if (i != set->items_len - 1) { - memmove (set->items + i, - set->items + i + 1, - (set->items_len - (i + 1)) * sizeof (key)); + if (index != set->items_len - 1u) { + memmove (set->items + index, + set->items + index + 1u, + (set->items_len - (index + 1u)) * sizeof (key)); } set->items_len--; @@ -115,7 +111,7 @@ mongoc_set_get (mongoc_set_t *set, uint32_t id) } void * -mongoc_set_get_item (mongoc_set_t *set, int idx) +mongoc_set_get_item (mongoc_set_t *set, size_t idx) { BSON_ASSERT (set); BSON_ASSERT (idx < set->items_len); @@ -125,7 +121,9 @@ mongoc_set_get_item (mongoc_set_t *set, int idx) void * -mongoc_set_get_item_and_id (mongoc_set_t *set, int idx, uint32_t *id /* OUT */) +mongoc_set_get_item_and_id (mongoc_set_t *set, + size_t idx, + uint32_t *id /* OUT */) { BSON_ASSERT (set); BSON_ASSERT (id); @@ -140,10 +138,8 @@ mongoc_set_get_item_and_id (mongoc_set_t *set, int idx, uint32_t *id /* OUT */) void mongoc_set_destroy (mongoc_set_t *set) { - int i; - if (set->dtor) { - for (i = 0; i < set->items_len; i++) { + for (size_t i = 0u; i < set->items_len; i++) { set->dtor (set->items[i].item, set->dtor_ctx); } } @@ -186,11 +182,10 @@ mongoc_set_for_each_with_id (mongoc_set_t *set, mongoc_set_for_each_with_id_cb_t cb, void *ctx) { - size_t i; mongoc_set_item_t *old_set; - size_t items_len; - items_len = set->items_len; + BSON_ASSERT (bson_in_range_unsigned (uint32_t, set->items_len)); + const uint32_t items_len = (uint32_t) set->items_len; /* prevent undefined behavior of memcpy(NULL) */ if (items_len == 0) { @@ -200,7 +195,7 @@ mongoc_set_for_each_with_id (mongoc_set_t *set, old_set = (mongoc_set_item_t *) bson_malloc (sizeof (*old_set) * items_len); memcpy (old_set, set->items, sizeof (*old_set) * items_len); - for (i = 0; i < items_len; i++) { + for (uint32_t i = 0u; i < items_len; i++) { if (!cb (i, old_set[i].item, ctx)) { break; } diff --git a/src/mongoc/mongoc-shared.c b/src/mongoc/mongoc-shared.c index c0fd68c4..a93824e3 100644 --- a/src/mongoc/mongoc-shared.c +++ b/src/mongoc/mongoc-shared.c @@ -42,9 +42,9 @@ static BSON_ONCE_FUN (_init_mtx) } void -mongoc_shared_ptr_reset (mongoc_shared_ptr *const ptr, - void *const pointee, - void (*const deleter) (void *)) +mongoc_shared_ptr_reset (mongoc_shared_ptr *ptr, + void *pointee, + void (*deleter) (void *)) { BSON_ASSERT_PARAM (ptr); if (!mongoc_shared_ptr_is_null (*ptr)) { @@ -65,14 +65,13 @@ mongoc_shared_ptr_reset (mongoc_shared_ptr *const ptr, } void -mongoc_shared_ptr_assign (mongoc_shared_ptr *const out, - mongoc_shared_ptr const from) +mongoc_shared_ptr_assign (mongoc_shared_ptr *dest, mongoc_shared_ptr from) { /* Copy from 'from' *first*, since this might be a self-assignment. */ mongoc_shared_ptr copied = mongoc_shared_ptr_copy (from); - BSON_ASSERT_PARAM (out); - mongoc_shared_ptr_reset_null (out); - *out = copied; + BSON_ASSERT_PARAM (dest); + mongoc_shared_ptr_reset_null (dest); + *dest = copied; } mongoc_shared_ptr @@ -84,19 +83,18 @@ mongoc_shared_ptr_create (void *pointee, void (*deleter) (void *)) } void -mongoc_atomic_shared_ptr_store (mongoc_shared_ptr *const out, - mongoc_shared_ptr const from) +mongoc_atomic_shared_ptr_store (mongoc_shared_ptr *dest, mongoc_shared_ptr from) { mongoc_shared_ptr prev = MONGOC_SHARED_PTR_NULL; - BSON_ASSERT_PARAM (out); + BSON_ASSERT_PARAM (dest); /* We are effectively "copying" the 'from' */ (void) mongoc_shared_ptr_copy (from); bson_shared_mutex_lock (&g_shared_ptr_mtx); /* Do the exchange. Quick! */ - prev = *out; - *out = from; + prev = *dest; + *dest = from; bson_shared_mutex_unlock (&g_shared_ptr_mtx); /* Free the pointer that we just overwrote */ @@ -115,7 +113,7 @@ mongoc_atomic_shared_ptr_load (mongoc_shared_ptr const *ptr) } mongoc_shared_ptr -mongoc_shared_ptr_copy (mongoc_shared_ptr const ptr) +mongoc_shared_ptr_copy (mongoc_shared_ptr ptr) { mongoc_shared_ptr ret = ptr; if (!mongoc_shared_ptr_is_null (ptr)) { @@ -126,7 +124,7 @@ mongoc_shared_ptr_copy (mongoc_shared_ptr const ptr) } void -mongoc_shared_ptr_reset_null (mongoc_shared_ptr *const ptr) +mongoc_shared_ptr_reset_null (mongoc_shared_ptr *ptr) { int prevcount = 0; BSON_ASSERT_PARAM (ptr); @@ -147,7 +145,7 @@ mongoc_shared_ptr_reset_null (mongoc_shared_ptr *const ptr) } int -mongoc_shared_ptr_use_count (mongoc_shared_ptr const ptr) +mongoc_shared_ptr_use_count (mongoc_shared_ptr ptr) { BSON_ASSERT ( !mongoc_shared_ptr_is_null (ptr) && diff --git a/src/mongoc/mongoc-sleep.h b/src/mongoc/mongoc-sleep.h new file mode 100644 index 00000000..db64535d --- /dev/null +++ b/src/mongoc/mongoc-sleep.h @@ -0,0 +1,40 @@ +#include "mongoc-prelude.h" + +#ifndef MONGOC_SLEEP_H +#define MONGOC_SLEEP_H + +#include + +#include "mongoc-macros.h" + +BSON_BEGIN_DECLS + +/** + * mongoc_usleep_func_t: + * @usec: Number of microseconds to sleep for. + * @user_data: User data provided to mongoc_client_set_usleep_impl(). + */ +typedef void (*mongoc_usleep_func_t) (int64_t usec, void *user_data); + +/** + * mongoc_client_set_usleep_impl: + * @usleep_func: A function to perform microsecond sleep. + * + * Sets the function to be called to perform sleep during scanning. + * Returns the old function. + * If old_user_data is not NULL, *old_user_data is set to the old user_data. + * Not thread-safe. + * Providing a `usleep_func` that does not sleep (e.g. coroutine suspension) is + * not supported. Doing so is at the user's own risk. + */ +MONGOC_EXPORT (void) +mongoc_client_set_usleep_impl (mongoc_client_t *client, + mongoc_usleep_func_t usleep_func, + void *user_data); + +MONGOC_EXPORT (void) +mongoc_usleep_default_impl (int64_t usec, void *user_data); + +BSON_END_DECLS + +#endif /* MONGOC_SLEEP_H */ diff --git a/src/mongoc/mongoc-socket.c b/src/mongoc/mongoc-socket.c index 93e34dd0..a77d805f 100644 --- a/src/mongoc/mongoc-socket.c +++ b/src/mongoc/mongoc-socket.c @@ -292,7 +292,6 @@ mongoc_socket_poll (mongoc_socket_poll_t *sds, /* IN */ struct pollfd *pfds; #endif int ret; - int i; ENTRY; @@ -303,7 +302,7 @@ mongoc_socket_poll (mongoc_socket_poll_t *sds, /* IN */ FD_ZERO (&write_fds); FD_ZERO (&error_fds); - for (i = 0; i < nsds; i++) { + for (size_t i = 0u; i < nsds; i++) { if (sds[i].events & POLLIN) { FD_SET (sds[i].socket->sd, &read_fds); } @@ -325,7 +324,7 @@ mongoc_socket_poll (mongoc_socket_poll_t *sds, /* IN */ return -1; } - for (i = 0; i < nsds; i++) { + for (size_t i = 0u; i < nsds; i++) { if (FD_ISSET (sds[i].socket->sd, &read_fds)) { sds[i].revents = POLLIN; } else if (FD_ISSET (sds[i].socket->sd, &write_fds)) { @@ -339,14 +338,14 @@ mongoc_socket_poll (mongoc_socket_poll_t *sds, /* IN */ #else pfds = (struct pollfd *) bson_malloc (sizeof (*pfds) * nsds); - for (i = 0; i < nsds; i++) { + for (size_t i = 0u; i < nsds; i++) { pfds[i].fd = sds[i].socket->sd; pfds[i].events = sds[i].events | POLLERR | POLLHUP; pfds[i].revents = 0; } ret = poll (pfds, nsds, timeout); - for (i = 0; i < nsds; i++) { + for (size_t i = 0u; i < nsds; i++) { sds[i].revents = pfds[i].revents; } @@ -1215,8 +1214,6 @@ _mongoc_socket_try_sendv_slow (mongoc_socket_t *sock, /* IN */ size_t iovcnt) /* IN */ { ssize_t ret = 0; - size_t i; - ssize_t wrote; ENTRY; @@ -1224,11 +1221,13 @@ _mongoc_socket_try_sendv_slow (mongoc_socket_t *sock, /* IN */ BSON_ASSERT (iov); BSON_ASSERT (iovcnt); - for (i = 0; i < iovcnt; i++) { - wrote = send (sock->sd, iov[i].iov_base, iov[i].iov_len, 0); + for (size_t i = 0u; i < iovcnt; i++) { #ifdef _WIN32 + BSON_ASSERT (bson_in_range_unsigned (int, iov[i].iov_len)); + const int wrote = send (sock->sd, iov[i].iov_base, (int) iov[i].iov_len, 0); if (wrote == SOCKET_ERROR) { #else + const ssize_t wrote = send (sock->sd, iov[i].iov_base, iov[i].iov_len, 0); if (wrote == -1) { #endif _mongoc_socket_capture_errno (sock); @@ -1241,7 +1240,7 @@ _mongoc_socket_try_sendv_slow (mongoc_socket_t *sock, /* IN */ ret += wrote; - if (wrote != iov[i].iov_len) { + if (bson_cmp_not_equal_su (wrote, iov[i].iov_len)) { RETURN (ret); } } @@ -1291,8 +1290,14 @@ _mongoc_socket_try_sendv (mongoc_socket_t *sock, /* IN */ DUMP_IOVEC (sendbuf, iov, iovcnt); #ifdef _WIN32 - ret = WSASend ( - sock->sd, (LPWSABUF) iov, iovcnt, &dwNumberofBytesSent, 0, NULL, NULL); + BSON_ASSERT (bson_in_range_unsigned (unsigned_long, iovcnt)); + ret = WSASend (sock->sd, + (LPWSABUF) iov, + (DWORD) iovcnt, + &dwNumberofBytesSent, + 0, + NULL, + NULL); TRACE ("WSASend sent: %ld (out of: %zu), ret: %d", dwNumberofBytesSent, iov->iov_len, @@ -1300,7 +1305,7 @@ _mongoc_socket_try_sendv (mongoc_socket_t *sock, /* IN */ #else memset (&msg, 0, sizeof msg); msg.msg_iov = iov; - msg.msg_iovlen = (int) iovcnt; + msg.msg_iovlen = iovcnt; ret = sendmsg (sock->sd, &msg, #ifdef MSG_NOSIGNAL @@ -1308,7 +1313,7 @@ _mongoc_socket_try_sendv (mongoc_socket_t *sock, /* IN */ #else 0); #endif - TRACE ("Send %ld out of %ld bytes", ret, iov->iov_len); + TRACE ("Send %zu out of %zu bytes", ret, iov->iov_len); #endif diff --git a/src/mongoc/mongoc-sspi.c b/src/mongoc/mongoc-sspi.c index 36cf03ab..e9deb94f 100644 --- a/src/mongoc/mongoc-sspi.c +++ b/src/mongoc/mongoc-sspi.c @@ -40,15 +40,15 @@ _mongoc_sspi_destroy_sspi_client_state (mongoc_sspi_client_state_t *state) state->haveCred = 0; } if (state->spn != NULL) { - free (state->spn); + bson_free (state->spn); state->spn = NULL; } if (state->response != NULL) { - free (state->response); + bson_free (state->response); state->response = NULL; } if (state->username != NULL) { - free (state->username); + bson_free (state->username); state->username = NULL; } } @@ -86,7 +86,7 @@ _mongoc_sspi_base64_encode (const SEC_CHAR *value, DWORD vlen) CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &len)) { - out = (SEC_CHAR *) malloc (sizeof (SEC_CHAR) * len); + out = (SEC_CHAR *) bson_malloc (sizeof (SEC_CHAR) * len); if (out) { /* Encode to the out buffer. */ if (CryptBinaryToStringA ((BYTE *) value, @@ -96,7 +96,7 @@ _mongoc_sspi_base64_encode (const SEC_CHAR *value, DWORD vlen) &len)) { return out; } else { - free (out); + bson_free (out); } } } @@ -111,7 +111,7 @@ _mongoc_sspi_base64_decode (const SEC_CHAR *value, DWORD *rlen) /* Get the correct size for the out buffer. */ if (CryptStringToBinaryA ( value, 0, CRYPT_STRING_BASE64, NULL, rlen, NULL, NULL)) { - out = (SEC_CHAR *) malloc (sizeof (SEC_CHAR) * *rlen); + out = (SEC_CHAR *) bson_malloc (sizeof (SEC_CHAR) * *rlen); if (out) { /* Decode to the out buffer. */ if (CryptStringToBinaryA (value, @@ -123,7 +123,7 @@ _mongoc_sspi_base64_decode (const SEC_CHAR *value, DWORD *rlen) NULL)) { return out; } else { - free (out); + bson_free (out); } } } @@ -137,11 +137,11 @@ _mongoc_sspi_wide_to_utf8 (WCHAR *value) CHAR *out; int len = WideCharToMultiByte (CP_UTF8, 0, value, -1, NULL, 0, NULL, NULL); if (len) { - out = (CHAR *) malloc (sizeof (CHAR) * len); + out = (CHAR *) bson_malloc (sizeof (CHAR) * len); if (WideCharToMultiByte (CP_UTF8, 0, value, -1, out, len, NULL, NULL)) { return out; } else { - free (out); + bson_free (out); } } _mongoc_sspi_set_gsserror (GetLastError (), "WideCharToMultiByte"); @@ -204,7 +204,7 @@ _mongoc_sspi_auth_sspi_client_init (WCHAR *service, /* LogonID (We don't use this) */ NULL, /* AuthData */ - user ? &authIdentity : NULL, + password ? &authIdentity : NULL, /* Always NULL */ NULL, /* Always NULL */ @@ -234,7 +234,7 @@ _mongoc_sspi_auth_sspi_client_step (mongoc_sspi_client_state_t *state, DWORD len; if (state->response != NULL) { - free (state->response); + bson_free (state->response); state->response = NULL; } @@ -319,7 +319,7 @@ _mongoc_sspi_auth_sspi_client_step (mongoc_sspi_client_state_t *state, } done: if (inBufs[0].pvBuffer) { - free (inBufs[0].pvBuffer); + bson_free (inBufs[0].pvBuffer); } if (outBufs[0].pvBuffer) { FreeContextBuffer (outBufs[0].pvBuffer); @@ -340,7 +340,7 @@ _mongoc_sspi_auth_sspi_client_unwrap (mongoc_sspi_client_state_t *state, wrapBufDesc.pBuffers = wrapBufs; if (state->response != NULL) { - free (state->response); + bson_free (state->response); state->response = NULL; state->qop = SECQOP_WRAP_NO_ENCRYPT; } @@ -377,7 +377,7 @@ _mongoc_sspi_auth_sspi_client_unwrap (mongoc_sspi_client_state_t *state, } done: if (wrapBufs[0].pvBuffer) { - free (wrapBufs[0].pvBuffer); + bson_free (wrapBufs[0].pvBuffer); } return status; } @@ -402,7 +402,7 @@ _mongoc_sspi_auth_sspi_client_wrap (mongoc_sspi_client_state_t *state, ULONG plaintextMessageSize; if (state->response != NULL) { - free (state->response); + bson_free (state->response); state->response = NULL; } @@ -428,9 +428,9 @@ _mongoc_sspi_auth_sspi_client_wrap (mongoc_sspi_client_state_t *state, inbufSize = sizes.cbSecurityTrailer + plaintextMessageSize + sizes.cbBlockSize; - inbuf = (SEC_CHAR *) malloc (inbufSize); + inbuf = (SEC_CHAR *) bson_malloc (inbufSize); if (inbuf == NULL) { - free (decodedData); + bson_free (decodedData); return MONGOC_SSPI_AUTH_GSS_ERROR; } @@ -453,7 +453,7 @@ _mongoc_sspi_auth_sspi_client_wrap (mongoc_sspi_client_state_t *state, inbufSize - sizes.cbSecurityTrailer, decodedData, plaintextMessageSize); - free (decodedData); + bson_free (decodedData); } wrapBufDesc.cBuffers = 3; @@ -476,14 +476,14 @@ _mongoc_sspi_auth_sspi_client_wrap (mongoc_sspi_client_state_t *state, status = EncryptMessage ( &state->ctx, protect ? 0 : SECQOP_WRAP_NO_ENCRYPT, &wrapBufDesc, 0); if (status != SEC_E_OK) { - free (inbuf); + bson_free (inbuf); _mongoc_sspi_set_gsserror (status, "EncryptMessage"); return MONGOC_SSPI_AUTH_GSS_ERROR; } outbufSize = wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer + wrapBufs[2].cbBuffer; - outbuf = (SEC_CHAR *) malloc (sizeof (SEC_CHAR) * outbufSize); + outbuf = (SEC_CHAR *) bson_malloc (sizeof (SEC_CHAR) * outbufSize); memcpy_s (outbuf, outbufSize, wrapBufs[0].pvBuffer, wrapBufs[0].cbBuffer); memcpy_s (outbuf + wrapBufs[0].cbBuffer, outbufSize - wrapBufs[0].cbBuffer, @@ -499,8 +499,8 @@ _mongoc_sspi_auth_sspi_client_wrap (mongoc_sspi_client_state_t *state, } else { status = MONGOC_SSPI_AUTH_GSS_COMPLETE; } - free (inbuf); - free (outbuf); + bson_free (inbuf); + bson_free (outbuf); return status; } diff --git a/src/mongoc/mongoc-stream-file.c b/src/mongoc/mongoc-stream-file.c index 6aa3db4d..104078df 100644 --- a/src/mongoc/mongoc-stream-file.c +++ b/src/mongoc/mongoc-stream-file.c @@ -128,13 +128,12 @@ _mongoc_stream_file_readv (mongoc_stream_t *stream, /* IN */ #ifdef _WIN32 { - ssize_t nread; - size_t i; - ENTRY; - for (i = 0; i < iovcnt; i++) { - nread = _read (file->fd, iov[i].iov_base, iov[i].iov_len); + for (size_t i = 0u; i < iovcnt; i++) { + BSON_ASSERT (bson_in_range_unsigned (unsigned_int, iov[i].iov_len)); + const int nread = + _read (file->fd, iov[i].iov_base, (unsigned int) iov[i].iov_len); if (nread < 0) { ret = ret ? ret : -1; GOTO (done); @@ -155,6 +154,7 @@ _mongoc_stream_file_readv (mongoc_stream_t *stream, /* IN */ #else { ENTRY; + BSON_ASSERT (bson_in_range_unsigned (int, iovcnt)); ret = readv (file->fd, iov, (int) iovcnt); GOTO (done); } @@ -180,12 +180,11 @@ _mongoc_stream_file_writev (mongoc_stream_t *stream, /* IN */ #ifdef _WIN32 { - ssize_t nwrite; - size_t i; - - for (i = 0; i < iovcnt; i++) { - nwrite = _write (file->fd, iov[i].iov_base, iov[i].iov_len); - if (nwrite != iov[i].iov_len) { + for (size_t i = 0; i < iovcnt; i++) { + BSON_ASSERT (bson_in_range_unsigned (unsigned_int, iov[i].iov_len)); + const int nwrite = + _write (file->fd, iov[i].iov_base, (unsigned int) iov[i].iov_len); + if (bson_cmp_not_equal_su (nwrite, iov[i].iov_len)) { ret = ret ? ret : -1; goto done; } @@ -195,6 +194,7 @@ _mongoc_stream_file_writev (mongoc_stream_t *stream, /* IN */ } #else { + BSON_ASSERT (bson_in_range_unsigned (int, iovcnt)); ret = writev (file->fd, iov, (int) iovcnt); goto done; } diff --git a/src/mongoc/mongoc-stream-private.h b/src/mongoc/mongoc-stream-private.h index e0ba6b66..c2223b03 100644 --- a/src/mongoc/mongoc-stream-private.h +++ b/src/mongoc/mongoc-stream-private.h @@ -41,7 +41,7 @@ bool _mongoc_stream_writev_full (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, - int32_t timeout_msec, + int64_t timeout_msec, bson_error_t *error); mongoc_stream_t * diff --git a/src/mongoc/mongoc-stream-socket.c b/src/mongoc/mongoc-stream-socket.c index ee45e47c..dfdbf0af 100644 --- a/src/mongoc/mongoc-stream-socket.c +++ b/src/mongoc/mongoc-stream-socket.c @@ -220,7 +220,6 @@ _mongoc_stream_socket_poll (mongoc_stream_poll_t *streams, int32_t timeout_msec) { - int i; ssize_t ret = -1; mongoc_socket_poll_t *sds; mongoc_stream_socket_t *ss; @@ -229,7 +228,7 @@ _mongoc_stream_socket_poll (mongoc_stream_poll_t *streams, sds = (mongoc_socket_poll_t *) bson_malloc (sizeof (*sds) * nstreams); - for (i = 0; i < nstreams; i++) { + for (size_t i = 0u; i < nstreams; i++) { ss = (mongoc_stream_socket_t *) streams[i].stream; if (!ss->sock) { @@ -243,7 +242,7 @@ _mongoc_stream_socket_poll (mongoc_stream_poll_t *streams, ret = mongoc_socket_poll (sds, nstreams, timeout_msec); if (ret > 0) { - for (i = 0; i < nstreams; i++) { + for (size_t i = 0u; i < nstreams; i++) { streams[i].revents = sds[i].revents; } } diff --git a/src/mongoc/mongoc-stream-tls-openssl-bio.c b/src/mongoc/mongoc-stream-tls-openssl-bio.c index 64318ae9..45f2ef8a 100644 --- a/src/mongoc/mongoc-stream-tls-openssl-bio.c +++ b/src/mongoc/mongoc-stream-tls-openssl-bio.c @@ -74,7 +74,7 @@ BIO_set_init (BIO *b, int init) } BIO_METHOD * -mongoc_stream_tls_openssl_bio_meth_new () +mongoc_stream_tls_openssl_bio_meth_new (void) { BIO_METHOD *meth = NULL; @@ -201,7 +201,6 @@ mongoc_stream_tls_openssl_bio_read (BIO *b, char *buf, int len) { mongoc_stream_tls_t *tls; mongoc_stream_tls_openssl_t *openssl; - int ret; BSON_ASSERT (b); BSON_ASSERT (buf); @@ -213,11 +212,23 @@ mongoc_stream_tls_openssl_bio_read (BIO *b, char *buf, int len) RETURN (-1); } + if (len < 0) { + RETURN (-1); + } + + if (BSON_UNLIKELY (!bson_in_range_signed (int32_t, tls->timeout_msec))) { + // CDRIVER-4589 + MONGOC_ERROR ("timeout_msec value %" PRId64 + " exceeds supported 32-bit range", + tls->timeout_msec); + return -1; + } + openssl = (mongoc_stream_tls_openssl_t *) tls->ctx; errno = 0; - ret = (int) mongoc_stream_read ( - tls->base_stream, buf, len, 0, tls->timeout_msec); + const ssize_t ret = mongoc_stream_read ( + tls->base_stream, buf, (size_t) len, 0, (int32_t) tls->timeout_msec); BIO_clear_retry_flags (b); if ((ret <= 0) && MONGOC_ERRNO_IS_AGAIN (errno)) { @@ -228,7 +239,9 @@ mongoc_stream_tls_openssl_bio_read (BIO *b, char *buf, int len) BIO_set_retry_read (openssl->bio); } - RETURN (ret); + BSON_ASSERT (bson_in_range_signed (int, ret)); + + RETURN ((int) ret); } @@ -254,7 +267,6 @@ mongoc_stream_tls_openssl_bio_write (BIO *b, const char *buf, int len) mongoc_stream_tls_t *tls; mongoc_stream_tls_openssl_t *openssl; mongoc_iovec_t iov; - int ret; ENTRY; BSON_ASSERT (b); @@ -266,21 +278,33 @@ mongoc_stream_tls_openssl_bio_write (BIO *b, const char *buf, int len) RETURN (-1); } + if (len < 0) { + RETURN (-1); + } + openssl = (mongoc_stream_tls_openssl_t *) tls->ctx; iov.iov_base = (void *) buf; - iov.iov_len = len; + iov.iov_len = (size_t) len; + + if (BSON_UNLIKELY (!bson_in_range_signed (int32_t, tls->timeout_msec))) { + // CDRIVER-4589 + MONGOC_ERROR ("timeout_msec value %" PRId64 + " exceeds supported 32-bit range", + tls->timeout_msec); + RETURN (-1); + } errno = 0; TRACE ("mongoc_stream_writev is expected to write: %d", len); - ret = - (int) mongoc_stream_writev (tls->base_stream, &iov, 1, tls->timeout_msec); + const ssize_t ret = mongoc_stream_writev ( + tls->base_stream, &iov, 1, (int32_t) tls->timeout_msec); BIO_clear_retry_flags (b); if (len > ret) { - TRACE ("Returned short write: %d of %d", ret, len); + TRACE ("Returned short write: %zd of %d", ret, len); } else { - TRACE ("Completed the %d", ret); + TRACE ("Completed the %zd", ret); } if (ret <= 0 && MONGOC_ERRNO_IS_AGAIN (errno)) { /* this BIO is not the same as "b", which openssl passed in to this func. @@ -291,7 +315,9 @@ mongoc_stream_tls_openssl_bio_write (BIO *b, const char *buf, int len) BIO_set_retry_write (openssl->bio); } - RETURN (ret); + BSON_ASSERT (bson_in_range_signed (int, ret)); + + RETURN ((int) ret); } diff --git a/src/mongoc/mongoc-stream-tls-openssl.c b/src/mongoc/mongoc-stream-tls-openssl.c index 3f88cdb0..1c720900 100644 --- a/src/mongoc/mongoc-stream-tls-openssl.c +++ b/src/mongoc/mongoc-stream-tls-openssl.c @@ -210,10 +210,11 @@ _mongoc_stream_tls_openssl_write (mongoc_stream_tls_t *tls, BSON_ASSERT (buf_len); if (tls->timeout_msec >= 0) { - expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL); + expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000); } - ret = BIO_write (openssl->bio, buf, buf_len); + BSON_ASSERT (bson_in_range_unsigned (int, buf_len)); + ret = BIO_write (openssl->bio, buf, (int) buf_len); if (ret <= 0) { return ret; @@ -223,13 +224,13 @@ _mongoc_stream_tls_openssl_write (mongoc_stream_tls_t *tls, now = bson_get_monotonic_time (); if ((expire - now) < 0) { - if (ret < buf_len) { + if (bson_cmp_less_su (ret, buf_len)) { mongoc_counter_streams_timeout_inc (); } tls->timeout_msec = 0; } else { - tls->timeout_msec = (expire - now) / 1000L; + tls->timeout_msec = (expire - now) / 1000; } } @@ -298,9 +299,12 @@ _mongoc_stream_tls_openssl_writev (mongoc_stream_t *stream, iov_pos = 0; while (iov_pos < iov[i].iov_len) { + BSON_ASSERT (buf_end >= buf_tail); + const size_t buf_remaining = (size_t) (buf_end - buf_tail); + if (buf_head != buf_tail || ((i + 1 < iovcnt) && - ((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) { + (buf_remaining > (iov[i].iov_len - iov_pos)))) { /* If we have either of: * - buffered bytes already * - another iovec to send after this one and we don't have more @@ -308,7 +312,7 @@ _mongoc_stream_tls_openssl_writev (mongoc_stream_t *stream, * * copy into the buffer */ - bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail); + bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_remaining); memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes); buf_tail += bytes; @@ -318,7 +322,7 @@ _mongoc_stream_tls_openssl_writev (mongoc_stream_t *stream, /* If we're full, request send */ to_write = buf_head; - to_write_len = buf_tail - buf_head; + to_write_len = (size_t) (buf_tail - buf_head); buf_tail = buf_head = buf; } @@ -337,15 +341,15 @@ _mongoc_stream_tls_openssl_writev (mongoc_stream_t *stream, child_ret = _mongoc_stream_tls_openssl_write (tls, to_write, to_write_len); - if (child_ret != to_write_len) { - TRACE ("Got child_ret: %ld while to_write_len is: %ld", + if (bson_cmp_not_equal_su (child_ret, to_write_len)) { + TRACE ("Got child_ret: %zu while to_write_len is: %zu", child_ret, to_write_len); } if (child_ret < 0) { - TRACE ("Returning what I had (%ld) as apposed to the error " - "(%ld, errno:%d)", + TRACE ("Returning what I had (%zu) as apposed to the error " + "(%zu, errno:%d)", ret, child_ret, errno); @@ -354,7 +358,7 @@ _mongoc_stream_tls_openssl_writev (mongoc_stream_t *stream, ret += child_ret; - if (child_ret < to_write_len) { + if (bson_cmp_less_su (child_ret, to_write_len)) { /* we timed out, so send back what we could send */ RETURN (ret); diff --git a/src/mongoc/mongoc-stream-tls-private.h b/src/mongoc/mongoc-stream-tls-private.h index 189047de..e3da5f26 100644 --- a/src/mongoc/mongoc-stream-tls-private.h +++ b/src/mongoc/mongoc-stream-tls-private.h @@ -37,7 +37,7 @@ struct _mongoc_stream_tls_t { mongoc_stream_t parent; /* The TLS stream wrapper */ mongoc_stream_t *base_stream; /* The underlying actual stream */ void *ctx; /* TLS lib specific configuration or wrappers */ - int32_t timeout_msec; + int64_t timeout_msec; mongoc_ssl_opt_t ssl_opts; bool (*handshake) (mongoc_stream_t *stream, const char *host, diff --git a/src/mongoc/mongoc-stream-tls-secure-channel.c b/src/mongoc/mongoc-stream-tls-secure-channel.c index f78913c7..ee936275 100644 --- a/src/mongoc/mongoc-stream-tls-secure-channel.c +++ b/src/mongoc/mongoc-stream-tls-secure-channel.c @@ -86,11 +86,6 @@ #define SP_PROT_TLS1_2_CLIENT 0x00000800 #endif -size_t -mongoc_secure_channel_write (mongoc_stream_tls_t *tls, - const void *data, - size_t data_length); - static void _mongoc_stream_tls_secure_channel_destroy (mongoc_stream_t *stream) @@ -381,9 +376,12 @@ _mongoc_stream_tls_secure_channel_writev (mongoc_stream_t *stream, TRACE ("iov %zu size: %zu", i, iov[i].iov_len); while (iov_pos < iov[i].iov_len) { + BSON_ASSERT (buf_end >= buf_tail); + const size_t buf_remaining = (size_t) (buf_end - buf_tail); + if (buf_head != buf_tail || - ((i + 1 < iovcnt) && - ((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) { + ((i + 1u < iovcnt) && + (buf_remaining > (iov[i].iov_len - iov_pos)))) { /* If we have either of: * - buffered bytes already * - another iovec to send after this one and we don't have more @@ -391,7 +389,7 @@ _mongoc_stream_tls_secure_channel_writev (mongoc_stream_t *stream, * * copy into the buffer */ - bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail); + bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_remaining); memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes); buf_tail += bytes; @@ -831,7 +829,7 @@ mongoc_stream_tls_secure_channel_handshake (mongoc_stream_t *stream, error->code = 0; } - TRACE ("Getting ready for state: %d, timeout is %d", + TRACE ("Getting ready for state: %d, timeout is %" PRId64, secure_channel->connecting_state + 1, tls->timeout_msec); diff --git a/src/mongoc/mongoc-stream-tls.c b/src/mongoc/mongoc-stream-tls.c index 8eecc574..dcf9b4bd 100644 --- a/src/mongoc/mongoc-stream-tls.c +++ b/src/mongoc/mongoc-stream-tls.c @@ -79,11 +79,10 @@ mongoc_stream_tls_handshake_block (mongoc_stream_t *stream, int events; ssize_t ret = 0; mongoc_stream_poll_t poller; - int64_t now; int64_t expire = 0; if (timeout_msec >= 0) { - expire = bson_get_monotonic_time () + (timeout_msec * 1000UL); + expire = bson_get_monotonic_time () + (timeout_msec * 1000); } /* @@ -109,16 +108,19 @@ mongoc_stream_tls_handshake_block (mongoc_stream_t *stream, poller.events = events; poller.revents = 0; - if (expire) { - now = bson_get_monotonic_time (); - if ((expire - now) < 0) { + if (expire >= 0) { + const int64_t now = bson_get_monotonic_time (); + const int64_t remaining = expire - now; + if (remaining < 0) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "TLS handshake timed out."); return false; } else { - timeout_msec = (expire - now) / 1000L; + const int64_t msec = remaining / 1000; + BSON_ASSERT (bson_in_range_signed (int32_t, msec)); + timeout_msec = (int32_t) msec; } } ret = mongoc_stream_poll (&poller, 1, timeout_msec); diff --git a/src/mongoc/mongoc-stream.c b/src/mongoc/mongoc-stream.c index 45b66366..99a619fb 100644 --- a/src/mongoc/mongoc-stream.c +++ b/src/mongoc/mongoc-stream.c @@ -157,6 +157,7 @@ mongoc_stream_writev (mongoc_stream_t *stream, BSON_ASSERT (stream->writev); + // CDRIVER-4781: for backward compatibility. if (timeout_msec < 0) { timeout_msec = MONGOC_DEFAULT_TIMEOUT_MSEC; } @@ -346,18 +347,17 @@ mongoc_stream_poll (mongoc_stream_poll_t *streams, mongoc_stream_poll_t *poller = (mongoc_stream_poll_t *) bson_malloc (sizeof (*poller) * nstreams); - int i; int last_type = 0; ssize_t rval = -1; errno = 0; - for (i = 0; i < nstreams; i++) { + for (size_t i = 0u; i < nstreams; i++) { poller[i].stream = mongoc_stream_get_root_stream (streams[i].stream); poller[i].events = streams[i].events; poller[i].revents = 0; - if (i == 0) { + if (i == 0u) { last_type = poller[i].stream->type; } else if (last_type != poller[i].stream->type) { errno = EINVAL; @@ -373,7 +373,7 @@ mongoc_stream_poll (mongoc_stream_poll_t *streams, rval = poller[0].stream->poll (poller, nstreams, timeout); if (rval > 0) { - for (i = 0; i < nstreams; i++) { + for (size_t i = 0u; i < nstreams; i++) { streams[i].revents = poller[i].revents; } } @@ -426,19 +426,29 @@ bool _mongoc_stream_writev_full (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, - int32_t timeout_msec, + int64_t timeout_msec, bson_error_t *error) { size_t total_bytes = 0; - int i; ssize_t r; ENTRY; - for (i = 0; i < iovcnt; i++) { + for (size_t i = 0u; i < iovcnt; i++) { total_bytes += iov[i].iov_len; } - r = mongoc_stream_writev (stream, iov, iovcnt, timeout_msec); + if (BSON_UNLIKELY (!bson_in_range_signed (int32_t, timeout_msec))) { + // CDRIVER-4589 + bson_set_error (error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_SOCKET, + "timeout_msec value %" PRId64 + " exceeds supported 32-bit range", + timeout_msec); + RETURN (false); + } + + r = mongoc_stream_writev (stream, iov, iovcnt, (int32_t) timeout_msec); TRACE ("writev returned: %zd", r); if (r < 0) { @@ -459,14 +469,14 @@ _mongoc_stream_writev_full (mongoc_stream_t *stream, RETURN (false); } - if (r != total_bytes) { + if (bson_cmp_not_equal_su (r, total_bytes)) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failure to send all requested bytes (only sent: %" PRIu64 - "/%" PRId64 " in %dms) during socket delivery", + "/%zu in %" PRId64 "ms) during socket delivery", (uint64_t) r, - (int64_t) total_bytes, + total_bytes, timeout_msec); RETURN (false); diff --git a/src/mongoc/mongoc-topology-background-monitoring.c b/src/mongoc/mongoc-topology-background-monitoring.c index e9378ecf..bcab5196 100644 --- a/src/mongoc/mongoc-topology-background-monitoring.c +++ b/src/mongoc/mongoc-topology-background-monitoring.c @@ -162,9 +162,17 @@ _mongoc_topology_background_monitoring_start (mongoc_topology_t *topology) _mongoc_topology_background_monitoring_reconcile (topology, tdmod.new_td); /* Start SRV polling thread. */ if (mongoc_topology_should_rescan_srv (topology)) { - topology->is_srv_polling = true; - mcommon_thread_create ( + int ret = mcommon_thread_create ( &topology->srv_polling_thread, srv_polling_run, topology); + if (ret == 0) { + topology->is_srv_polling = true; + } else { + char errmsg_buf[BSON_ERROR_BUFFER_SIZE]; + char *errmsg = bson_strerror_r (ret, errmsg_buf, sizeof errmsg_buf); + MONGOC_ERROR ("Failed to start SRV polling thread. SRV records " + "will not be polled. Error: %s", + errmsg); + } } } @@ -182,13 +190,12 @@ _remove_orphaned_server_monitors (mongoc_set_t *server_monitors, { uint32_t *server_monitor_ids_to_remove; uint32_t n_server_monitor_ids_to_remove = 0; - int i; /* Signal shutdown to server monitors no longer in the topology description. */ server_monitor_ids_to_remove = bson_malloc0 (sizeof (uint32_t) * server_monitors->items_len); - for (i = 0; i < server_monitors->items_len; i++) { + for (size_t i = 0u; i < server_monitors->items_len; i++) { mongoc_server_monitor_t *server_monitor; uint32_t id; @@ -204,7 +211,7 @@ _remove_orphaned_server_monitors (mongoc_set_t *server_monitors, } /* Remove freed server monitors that have completed shutdown. */ - for (i = 0; i < n_server_monitor_ids_to_remove; i++) { + for (uint32_t i = 0u; i < n_server_monitor_ids_to_remove; i++) { mongoc_set_rm (server_monitors, server_monitor_ids_to_remove[i]); } bson_free (server_monitor_ids_to_remove); @@ -223,7 +230,6 @@ _mongoc_topology_background_monitoring_reconcile ( mongoc_topology_t *topology, mongoc_topology_description_t *td) { mongoc_set_t *server_descriptions = mc_tpld_servers (td); - int i; BSON_ASSERT (!topology->single_threaded); @@ -234,7 +240,7 @@ _mongoc_topology_background_monitoring_reconcile ( } /* Add newly discovered server monitors, and update existing ones. */ - for (i = 0; i < server_descriptions->items_len; i++) { + for (size_t i = 0u; i < server_descriptions->items_len; i++) { mongoc_server_description_t *sd; sd = mongoc_set_get_item (server_descriptions, i); @@ -257,7 +263,6 @@ _mongoc_topology_background_monitoring_request_scan ( mongoc_topology_t *topology) { mongoc_set_t *server_monitors; - int i; BSON_ASSERT (!topology->single_threaded); @@ -269,7 +274,7 @@ _mongoc_topology_background_monitoring_request_scan ( server_monitors = topology->server_monitors; - for (i = 0; i < server_monitors->items_len; i++) { + for (size_t i = 0u; i < server_monitors->items_len; i++) { mongoc_server_monitor_t *server_monitor; uint32_t id; @@ -289,9 +294,6 @@ void _mongoc_topology_background_monitoring_stop (mongoc_topology_t *topology) { mongoc_server_monitor_t *server_monitor; - int i; - int n_srv_monitors; - int n_rtt_monitors; BSON_ASSERT (!topology->single_threaded); @@ -316,30 +318,30 @@ _mongoc_topology_background_monitoring_stop (mongoc_topology_t *topology) bson_mutex_unlock (&topology->srv_polling_mtx); bson_mutex_lock (&topology->tpld_modification_mtx); - n_srv_monitors = topology->server_monitors->items_len; - n_rtt_monitors = topology->rtt_monitors->items_len; + const size_t n_srv_monitors = topology->server_monitors->items_len; + const size_t n_rtt_monitors = topology->rtt_monitors->items_len; bson_mutex_unlock (&topology->tpld_modification_mtx); /* Signal all server monitors to shut down. */ - for (i = 0; i < n_srv_monitors; i++) { + for (size_t i = 0u; i < n_srv_monitors; i++) { server_monitor = mongoc_set_get_item (topology->server_monitors, i); mongoc_server_monitor_request_shutdown (server_monitor); } /* Signal all RTT monitors to shut down. */ - for (i = 0; i < n_rtt_monitors; i++) { + for (size_t i = 0u; i < n_rtt_monitors; i++) { server_monitor = mongoc_set_get_item (topology->rtt_monitors, i); mongoc_server_monitor_request_shutdown (server_monitor); } - for (i = 0; i < n_srv_monitors; i++) { + for (size_t i = 0u; i < n_srv_monitors; i++) { /* Wait for the thread to shutdown. */ server_monitor = mongoc_set_get_item (topology->server_monitors, i); mongoc_server_monitor_wait_for_shutdown (server_monitor); mongoc_server_monitor_destroy (server_monitor); } - for (i = 0; i < n_rtt_monitors; i++) { + for (size_t i = 0u; i < n_rtt_monitors; i++) { /* Wait for the thread to shutdown. */ server_monitor = mongoc_set_get_item (topology->rtt_monitors, i); mongoc_server_monitor_wait_for_shutdown (server_monitor); diff --git a/src/mongoc/mongoc-topology-description-apm.c b/src/mongoc/mongoc-topology-description-apm.c index c229a4df..318dac41 100644 --- a/src/mongoc/mongoc-topology-description-apm.c +++ b/src/mongoc/mongoc-topology-description-apm.c @@ -83,7 +83,6 @@ void _mongoc_topology_description_monitor_opening (mongoc_topology_description_t *td) { mongoc_topology_description_t *prev_td = NULL; - size_t i; mongoc_server_description_t *sd; if (td->opened) { @@ -111,8 +110,8 @@ _mongoc_topology_description_monitor_opening (mongoc_topology_description_t *td) _mongoc_topology_description_monitor_changed (prev_td, td); } - for (i = 0; i < mc_tpld_servers (td)->items_len; i++) { - sd = mongoc_set_get_item (mc_tpld_servers (td), (int) i); + for (size_t i = 0u; i < mc_tpld_servers (td)->items_len; i++) { + sd = mongoc_set_get_item (mc_tpld_servers (td), i); _mongoc_topology_description_monitor_server_opening (td, sd); } diff --git a/src/mongoc/mongoc-topology-description-private.h b/src/mongoc/mongoc-topology-description-private.h index 3a12b103..edafc769 100644 --- a/src/mongoc/mongoc-topology-description-private.h +++ b/src/mongoc/mongoc-topology-description-private.h @@ -24,6 +24,7 @@ #include "mongoc-array-private.h" #include "mongoc-topology-description.h" #include "mongoc-apm-private.h" +#include "mongoc-deprioritized-servers-private.h" typedef enum { @@ -114,6 +115,7 @@ mongoc_topology_description_select ( mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_pref, bool *must_use_primary, + const mongoc_deprioritized_servers_t *ds, int64_t local_threshold_ms); mongoc_server_description_t * @@ -149,7 +151,8 @@ mongoc_topology_description_suitable_servers ( const mongoc_topology_description_t *topology, const mongoc_read_prefs_t *read_pref, bool *must_use_primary, - size_t local_threshold_ms); + const mongoc_deprioritized_servers_t *ds, + int64_t local_threshold_ms); bool mongoc_topology_description_has_data_node ( @@ -194,4 +197,10 @@ _mongoc_topology_description_clear_connection_pool ( uint32_t server_id, const bson_oid_t *service_id); +void +mongoc_deprioritized_servers_add_if_sharded ( + mongoc_deprioritized_servers_t *ds, + mongoc_topology_description_type_t topology_type, + const mongoc_server_description_t *sd); + #endif /* MONGOC_TOPOLOGY_DESCRIPTION_PRIVATE_H */ diff --git a/src/mongoc/mongoc-topology-description.c b/src/mongoc/mongoc-topology-description.c index b4d6200a..fb885d69 100644 --- a/src/mongoc/mongoc-topology-description.c +++ b/src/mongoc/mongoc-topology-description.c @@ -121,7 +121,6 @@ _mongoc_topology_description_copy_to (const mongoc_topology_description_t *src, mongoc_topology_description_t *dst) { size_t nitems; - size_t i; const mongoc_server_description_t *sd; uint32_t id; @@ -139,9 +138,9 @@ _mongoc_topology_description_copy_to (const mongoc_topology_description_t *src, nitems = bson_next_power_of_two (mc_tpld_servers_const (src)->items_len); dst->_servers_ = mongoc_set_new (nitems, _mongoc_topology_server_dtor, NULL); - for (i = 0; i < mc_tpld_servers_const (src)->items_len; i++) { - sd = mongoc_set_get_item_and_id_const ( - mc_tpld_servers_const (src), (int) i, &id); + for (size_t i = 0u; i < mc_tpld_servers_const (src)->items_len; i++) { + sd = + mongoc_set_get_item_and_id_const (mc_tpld_servers_const (src), i, &id); mongoc_set_add ( mc_tpld_servers (dst), id, mongoc_server_description_new_copy (sd)); } @@ -312,6 +311,33 @@ _mongoc_topology_description_has_primary ( return primary; } +/* + *-------------------------------------------------------------------------- + * + * _mongoc_server_description_primary_is_not_stale -- + * + * Checks if a primary server is not stale by comparing the electionId and + * setVersion. + * + * Returns: + * True if the server's electionId is larger or the server's version is + * later than the topology max version. + * + * Side effects: + * None + * + *-------------------------------------------------------------------------- + */ +static bool +_mongoc_server_description_primary_is_not_stale ( + mongoc_topology_description_t *td, const mongoc_server_description_t *sd) +{ + /* initially max_set_version is -1 and max_election_id is zeroed */ + return (bson_oid_compare (&sd->election_id, &td->max_election_id) > 0) || + ((bson_oid_compare (&sd->election_id, &td->max_election_id) == 0) && + sd->set_version >= td->max_set_version); +} + /* *-------------------------------------------------------------------------- * @@ -488,7 +514,8 @@ _mongoc_try_mode_secondary (mongoc_array_t *set, /* OUT */ const mongoc_topology_description_t *topology, const mongoc_read_prefs_t *read_pref, bool *must_use_primary, - size_t local_threshold_ms) + const mongoc_deprioritized_servers_t *ds, + int64_t local_threshold_ms) { mongoc_read_prefs_t *secondary; @@ -500,26 +527,101 @@ _mongoc_try_mode_secondary (mongoc_array_t *set, /* OUT */ topology, secondary, must_use_primary, + ds, local_threshold_ms); mongoc_read_prefs_destroy (secondary); } -/* if any mongos are candidates, add them to the candidates array */ static bool -_mongoc_find_suitable_mongos_cb (const void *item, void *ctx) +_mongoc_td_servers_to_candidates_array (const void *item, void *ctx) { - const mongoc_server_description_t *server = item; - mongoc_suitable_data_t *data = (mongoc_suitable_data_t *) ctx; + BSON_ASSERT_PARAM (item); + BSON_ASSERT_PARAM (ctx); + + const mongoc_server_description_t *const server = item; + mongoc_suitable_data_t *const data = (mongoc_suitable_data_t *) ctx; + + data->candidates[data->candidates_len++] = server; - if (_mongoc_topology_description_server_is_candidate ( - server->type, data->read_mode, data->topology_type)) { - data->candidates[data->candidates_len++] = server; - } return true; } +// Server Selection Spec: If a list of deprioritized servers is provided, and +// the topology is a sharded cluster, these servers should be selected only if +// there are no other suitable servers. The server selection algorithm MUST +// ignore the deprioritized servers if the topology is not a sharded cluster. +static void +_mongoc_filter_deprioritized_servers (mongoc_suitable_data_t *data, + const mongoc_deprioritized_servers_t *ds) +{ + BSON_ASSERT_PARAM (data); + BSON_ASSERT_PARAM (ds); + + TRACE ("%s", "deprioritization: filtering list of candidates"); + + mongoc_array_t filtered_servers; + _mongoc_array_init (&filtered_servers, + sizeof (const mongoc_server_description_t *)); + + for (size_t idx = 0u; idx < data->candidates_len; ++idx) { + mongoc_server_description_t const *const sd = data->candidates[idx]; + + if (!mongoc_deprioritized_servers_contains (ds, sd)) { + TRACE ("deprioritization: - kept: %s (id: %" PRIu32 ")", + sd->host.host_and_port, + sd->id); + _mongoc_array_append_val (&filtered_servers, sd); + } else { + TRACE ("deprioritization: - removed: %s (id: %" PRIu32 ")", + sd->host.host_and_port, + sd->id); + } + } + + if (filtered_servers.len == 0u) { + TRACE ("%s", + "deprioritization: reverted due to no other suitable servers"); + _mongoc_array_destroy (&filtered_servers); + } else if (filtered_servers.len == data->candidates_len) { + TRACE ("%s", "deprioritization: none found in list of candidates"); + _mongoc_array_destroy (&filtered_servers); + } else { + TRACE ("%s", "deprioritization: using filtered list of candidates"); + data->candidates_len = filtered_servers.len; + // `(void*)`: avoid MSVC error C4090: + // 'function': different 'const' qualifiers + memmove ((void *) data->candidates, + filtered_servers.data, + filtered_servers.len * filtered_servers.element_size); + _mongoc_array_destroy (&filtered_servers); + } +} + + +// Keep only suitable mongoses in the candidates array. +static void +_mongoc_filter_suitable_mongos (mongoc_suitable_data_t *data) +{ + size_t idx = 0u; + + while (idx < data->candidates_len) { + if (_mongoc_topology_description_server_is_candidate ( + data->candidates[idx]->type, + data->read_mode, + data->topology_type)) { + // All candidates in the latency window are suitable. + ++idx; + } else { + // Remove from list using swap+pop. + // Order doesn't matter; the list will be randomized in + // mongoc_topology_description_select prior to server selection. + data->candidates[idx] = data->candidates[--data->candidates_len]; + } + } +} + /* *------------------------------------------------------------------------- @@ -541,11 +643,10 @@ int32_t mongoc_topology_description_lowest_max_wire_version ( const mongoc_topology_description_t *td) { - int i; int32_t ret = INT32_MAX; const mongoc_set_t *servers = mc_tpld_servers_const (td); - for (i = 0; (size_t) i < servers->items_len; i++) { + for (size_t i = 0u; (size_t) i < servers->items_len; i++) { const mongoc_server_description_t *sd = mongoc_set_get_item_const (servers, i); if (sd->type != MONGOC_SERVER_UNKNOWN && @@ -576,8 +677,8 @@ bool mongoc_topology_description_all_sds_have_write_date ( const mongoc_topology_description_t *td) { - int i; - for (i = 0; (size_t) i < mc_tpld_servers_const (td)->items_len; i++) { + for (size_t i = 0u; (size_t) i < mc_tpld_servers_const (td)->items_len; + i++) { const mongoc_server_description_t *sd = mongoc_set_get_item_const (mc_tpld_servers_const (td), i); @@ -740,24 +841,23 @@ mongoc_topology_description_suitable_servers ( const mongoc_topology_description_t *topology, const mongoc_read_prefs_t *read_pref, bool *must_use_primary, - size_t local_threshold_ms) + const mongoc_deprioritized_servers_t *ds, + int64_t local_threshold_ms) { - mongoc_suitable_data_t data; - const mongoc_set_t *td_servers = mc_tpld_servers_const (topology); - int64_t nearest = -1; - int i; const mongoc_read_mode_t given_read_mode = mongoc_read_prefs_get_mode (read_pref); const bool override_use_primary = _must_use_primary (topology, optype, given_read_mode); - data.primary = NULL; - data.topology_type = topology->type; - data.has_secondary = false; - data.candidates_len = 0; - data.candidates = bson_malloc0 (sizeof (mongoc_server_description_t *) * - td_servers->items_len); + mongoc_suitable_data_t data = { + .primary = NULL, + .topology_type = topology->type, + .has_secondary = false, + .candidates_len = 0, + .candidates = bson_malloc0 (sizeof (mongoc_server_description_t *) * + td_servers->items_len), + }; /* The "effective" read mode is the read mode that we should behave for, and * depends on the user's provided read mode, the type of operation that the @@ -820,8 +920,12 @@ mongoc_topology_description_suitable_servers ( if (data.read_mode == MONGOC_READ_SECONDARY_PREFERRED) { /* try read_mode SECONDARY */ - _mongoc_try_mode_secondary ( - set, topology, read_pref, must_use_primary, local_threshold_ms); + _mongoc_try_mode_secondary (set, + topology, + read_pref, + must_use_primary, + NULL, + local_threshold_ms); /* otherwise fall back to primary */ if (!set->len && data.primary) { @@ -832,7 +936,7 @@ mongoc_topology_description_suitable_servers ( } if (data.read_mode == MONGOC_READ_SECONDARY) { - for (i = 0; i < data.candidates_len; i++) { + for (size_t i = 0u; i < data.candidates_len; i++) { if (data.candidates[i] && data.candidates[i]->type != MONGOC_SERVER_RS_SECONDARY) { TRACE ("Rejected [%s] [%s] for mode [%s] with RS topology", @@ -871,11 +975,16 @@ mongoc_topology_description_suitable_servers ( } } - /* Sharded clusters -- - * All candidates in the latency window are suitable */ + // Sharded clusters -- if (topology->type == MONGOC_TOPOLOGY_SHARDED) { mongoc_set_for_each_const ( - td_servers, _mongoc_find_suitable_mongos_cb, &data); + td_servers, _mongoc_td_servers_to_candidates_array, &data); + + if (ds) { + _mongoc_filter_deprioritized_servers (&data, ds); + } + + _mongoc_filter_suitable_mongos (&data); } /* Load balanced clusters -- @@ -894,18 +1003,25 @@ mongoc_topology_description_suitable_servers ( * - primary_preferred and no primary read * - sharded anything * Find the nearest, then select within the window */ - - for (i = 0; i < data.candidates_len; i++) { - if (data.candidates[i] && - (nearest == -1 || - nearest > data.candidates[i]->round_trip_time_msec)) { - nearest = data.candidates[i]->round_trip_time_msec; + int64_t nearest = INT64_MAX; + bool found = false; + for (size_t i = 0u; i < data.candidates_len; i++) { + if (data.candidates[i]) { + nearest = BSON_MIN (nearest, data.candidates[i]->round_trip_time_msec); + found = true; } } - for (i = 0; i < data.candidates_len; i++) { - if (data.candidates[i] && (data.candidates[i]->round_trip_time_msec <= - nearest + local_threshold_ms)) { + // No candidates remaining. + if (!found) { + goto DONE; + } + + const int64_t rtt_limit = nearest + local_threshold_ms; + + for (size_t i = 0u; i < data.candidates_len; i++) { + if (data.candidates[i] && + (data.candidates[i]->round_trip_time_msec <= rtt_limit)) { _mongoc_array_append_val (set, data.candidates[i]); } } @@ -930,10 +1046,9 @@ bool mongoc_topology_description_has_data_node ( const mongoc_topology_description_t *td) { - int i; const mongoc_set_t *servers = mc_tpld_servers_const (td); - for (i = 0; i < (int) servers->items_len; i++) { + for (size_t i = 0u; i < servers->items_len; i++) { const mongoc_server_description_t *sd = mongoc_set_get_item_const (servers, i); if (_is_data_node (sd)) { @@ -969,16 +1084,16 @@ mongoc_topology_description_select ( mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_pref, bool *must_use_primary, + const mongoc_deprioritized_servers_t *ds, int64_t local_threshold_ms) { mongoc_array_t suitable_servers; - mongoc_server_description_t const *sd = NULL; - int rand_n; ENTRY; if (topology->type == MONGOC_TOPOLOGY_SINGLE) { - sd = mongoc_set_get_item_const (mc_tpld_servers_const (topology), 0); + mongoc_server_description_t const *const sd = + mongoc_set_get_item_const (mc_tpld_servers_const (topology), 0); if (optype == MONGOC_SS_AGGREGATE_WITH_WRITE && sd->max_wire_version < WIRE_VERSION_5_0) { @@ -1006,12 +1121,17 @@ mongoc_topology_description_select ( topology, read_pref, must_use_primary, + ds, local_threshold_ms); + + mongoc_server_description_t const *sd = NULL; + if (suitable_servers.len != 0) { - rand_n = _mongoc_rand_simple ((unsigned *) &topology->rand_seed); + const int rand_n = + _mongoc_rand_simple ((unsigned *) &topology->rand_seed); sd = _mongoc_array_index (&suitable_servers, mongoc_server_description_t *, - rand_n % suitable_servers.len); + (size_t) rand_n % suitable_servers.len); } _mongoc_array_destroy (&suitable_servers); @@ -1510,7 +1630,6 @@ _mongoc_topology_description_remove_unreported_servers ( const mongoc_server_description_t *primary) { mongoc_array_t to_remove; - int i; _mongoc_array_init (&to_remove, sizeof (mongoc_server_description_t *)); @@ -1519,7 +1638,7 @@ _mongoc_topology_description_remove_unreported_servers ( * mongoc_server_description_cleanup on the primary itself if it * doesn't report its own connection_address in its hosts list. * See hosts_differ_from_seeds.json */ - for (i = 0; i < mc_tpld_servers_const (topology)->items_len; i++) { + for (size_t i = 0u; i < mc_tpld_servers_const (topology)->items_len; i++) { const mongoc_server_description_t *member = mongoc_set_get_item_const (mc_tpld_servers_const (topology), i); const char *address = member->connection_address; @@ -1530,7 +1649,7 @@ _mongoc_topology_description_remove_unreported_servers ( /* now it's safe to call _mongoc_topology_description_remove_server, * even on the primary */ - for (i = 0; i < to_remove.len; i++) { + for (size_t i = 0u; i < to_remove.len; i++) { const mongoc_server_description_t *member = _mongoc_array_index (&to_remove, mongoc_server_description_t *, i); @@ -1631,15 +1750,13 @@ _mongoc_topology_description_update_rs_from_primary ( return; } } + if (server->max_wire_version >= WIRE_VERSION_6_0) { + /* MongoDB 6.0+ */ + if (_mongoc_server_description_primary_is_not_stale (topology, server)) { + _mongoc_topology_description_set_max_election_id (topology, server); + _mongoc_topology_description_set_max_set_version (topology, server); - if (mongoc_server_description_has_set_version (server) && - mongoc_server_description_has_election_id (server)) { - /* Server Discovery And Monitoring Spec: "The client remembers the - * greatest electionId reported by a primary, and distrusts primaries - * with lesser electionIds. This prevents the client from oscillating - * between the old and new primary during a split-brain period." - */ - if (_mongoc_topology_description_later_election (topology, server)) { + } else { bson_set_error (&error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, @@ -1649,17 +1766,37 @@ _mongoc_topology_description_update_rs_from_primary ( _update_rs_type (topology); return; } + } else { + // old comparison rules, namely setVersion is checked before electionId + if (mongoc_server_description_has_set_version (server) && + mongoc_server_description_has_election_id (server)) { + /* Server Discovery And Monitoring Spec: "The client remembers the + * greatest electionId reported by a primary, and distrusts primaries + * with lesser electionIds. This prevents the client from oscillating + * between the old and new primary during a split-brain period." + */ + if (_mongoc_topology_description_later_election (topology, server)) { + // stale primary code return: + bson_set_error (&error, + MONGOC_ERROR_STREAM, + MONGOC_ERROR_STREAM_CONNECT, + "member's setVersion or electionId is stale"); + mongoc_topology_description_invalidate_server ( + topology, server->id, &error); + _update_rs_type (topology); + return; + } - /* server's electionId >= topology's max electionId */ - _mongoc_topology_description_set_max_election_id (topology, server); - } + /* server's electionId >= topology's max electionId */ + _mongoc_topology_description_set_max_election_id (topology, server); + } - if (mongoc_server_description_has_set_version (server) && - (!_mongoc_topology_description_has_set_version (topology) || - server->set_version > topology->max_set_version)) { - _mongoc_topology_description_set_max_set_version (topology, server); + if (mongoc_server_description_has_set_version (server) && + (!_mongoc_topology_description_has_set_version (topology) || + server->set_version > topology->max_set_version)) { + _mongoc_topology_description_set_max_set_version (topology, server); + } } - /* 'Server' is the primary! Invalidate other primaries if found */ data.primary = server; data.topology = topology; @@ -2031,15 +2168,14 @@ _mongoc_topology_description_update_session_timeout ( mongoc_topology_description_t *td) { mongoc_set_t *set; - size_t i; mongoc_server_description_t *sd; set = mc_tpld_servers (td); td->session_timeout_minutes = MONGOC_NO_SESSIONS; - for (i = 0; i < set->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (set, (int) i); + for (size_t i = 0; i < set->items_len; i++) { + sd = (mongoc_server_description_t *) mongoc_set_get_item (set, i); if (!_is_data_node (sd)) { continue; } @@ -2073,14 +2209,13 @@ static void _mongoc_topology_description_check_compatible ( mongoc_topology_description_t *td) { - size_t i; mongoc_set_t const *const servers = mc_tpld_servers_const (td); memset (&td->compatibility_error, 0, sizeof (bson_error_t)); - for (i = 0; i < servers->items_len; i++) { + for (size_t i = 0; i < servers->items_len; i++) { mongoc_server_description_t const *const sd = - mongoc_set_get_item_const (servers, (int) i); + mongoc_set_get_item_const (servers, i); if (sd->type == MONGOC_SERVER_UNKNOWN || sd->type == MONGOC_SERVER_POSSIBLE_PRIMARY) { continue; @@ -2160,7 +2295,7 @@ mongoc_topology_description_handle_hello ( uint32_t len; bson_iter_document (&iter, &len, &bytes); - bson_init_static (&incoming_topology_version, bytes, len); + BSON_ASSERT (bson_init_static (&incoming_topology_version, bytes, len)); if (mongoc_server_description_topology_version_cmp ( &sd->topology_version, &incoming_topology_version) == 1) { @@ -2284,7 +2419,7 @@ mongoc_topology_description_has_readable_server ( /* local threshold argument doesn't matter */ return mongoc_topology_description_select ( - td, MONGOC_SS_READ, prefs, NULL, 0) != NULL; + td, MONGOC_SS_READ, prefs, NULL, NULL, 0) != NULL; } /* @@ -2311,7 +2446,7 @@ mongoc_topology_description_has_writable_server ( } return mongoc_topology_description_select ( - td, MONGOC_SS_WRITE, NULL, NULL, 0) != NULL; + td, MONGOC_SS_WRITE, NULL, NULL, NULL, 0) != NULL; } /* @@ -2372,7 +2507,6 @@ mongoc_server_description_t ** mongoc_topology_description_get_servers ( const mongoc_topology_description_t *td, size_t *n /* OUT */) { - size_t i; const mongoc_set_t *const set = mc_tpld_servers_const (BSON_ASSERT_PTR_INLINE (td)); /* enough room for all descriptions, even if some are unknown */ @@ -2383,9 +2517,9 @@ mongoc_topology_description_get_servers ( *n = 0; - for (i = 0; i < set->items_len; ++i) { + for (size_t i = 0; i < set->items_len; ++i) { const mongoc_server_description_t *sd = - mongoc_set_get_item_const (set, (int) i); + mongoc_set_get_item_const (set, i); if (sd->type != MONGOC_SERVER_UNKNOWN) { sds[*n] = mongoc_server_description_new_copy (sd); @@ -2559,3 +2693,21 @@ _mongoc_topology_description_clear_connection_pool ( mc_tpl_sd_increment_generation (sd, service_id); } + + +void +mongoc_deprioritized_servers_add_if_sharded ( + mongoc_deprioritized_servers_t *ds, + mongoc_topology_description_type_t topology_type, + const mongoc_server_description_t *sd) +{ + // In a sharded cluster, the server on which the operation failed MUST + // be provided to the server selection mechanism as a deprioritized + // server. + if (topology_type == MONGOC_TOPOLOGY_SHARDED) { + TRACE ("deprioritization: add to list: %s (id: %" PRIu32 ")", + sd->host.host_and_port, + sd->id); + mongoc_deprioritized_servers_add (ds, sd); + } +} diff --git a/src/mongoc/mongoc-topology-private.h b/src/mongoc/mongoc-topology-private.h index 4d37ddf3..2681001a 100644 --- a/src/mongoc/mongoc-topology-private.h +++ b/src/mongoc/mongoc-topology-private.h @@ -29,6 +29,7 @@ #include "mongoc-crypt-private.h" #include "mongoc-ts-pool-private.h" #include "mongoc-shared-private.h" +#include "mongoc-sleep.h" #define MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS 500 #define MONGOC_TOPOLOGY_SOCKET_CHECK_INTERVAL_MS 5000 @@ -212,6 +213,11 @@ typedef struct _mongoc_topology_t { * topology. This could occur if the URI is invalid. * An invalid topology does not monitor servers. */ bool valid; + + // `usleep_fn` and `usleep_data` may be overridden by + // `mongoc_client_set_usleep_impl`. + mongoc_usleep_func_t usleep_fn; + void *usleep_data; } mongoc_topology_t; mongoc_topology_t * @@ -278,6 +284,8 @@ mongoc_topology_select (mongoc_topology_t *topology, * @param must_use_primary An optional output parameter. Server selection might * need to override the caller's read preferences' read mode to 'primary'. * Whether or not that takes place will be set through this pointer. + * @param ds A list of servers that should be selected only if there are no + * other suitable servers. * @param error An output parameter for any error information. * @return uint32_t A non-zero integer ID of the server description. In case of * error, sets `error` and returns zero. @@ -289,6 +297,7 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_prefs, bool *must_use_primary, + const mongoc_deprioritized_servers_t *ds, bson_error_t *error); /** @@ -618,7 +627,7 @@ _mongoc_topology_invalidate_server (mongoc_topology_t *td, uint32_t server_id) */ const mongoc_host_list_t ** _mongoc_apply_srv_max_hosts (const mongoc_host_list_t *hl, - int32_t max_hosts, + size_t max_hosts, size_t *hl_array_size); @@ -627,4 +636,10 @@ _mongoc_apply_srv_max_hosts (const mongoc_host_list_t *hl, bool mongoc_topology_uses_server_api (const mongoc_topology_t *topology); + +/* Returns true if load balancing mode has been seelected, otherwise returns + * false. */ +bool +mongoc_topology_uses_loadbalanced (const mongoc_topology_t *topology); + #endif diff --git a/src/mongoc/mongoc-topology-scanner-private.h b/src/mongoc/mongoc-topology-scanner-private.h index ed1e273f..01e826fe 100644 --- a/src/mongoc/mongoc-topology-scanner-private.h +++ b/src/mongoc/mongoc-topology-scanner-private.h @@ -214,7 +214,6 @@ _mongoc_topology_scanner_add_speculative_authentication ( bson_t *cmd, const mongoc_uri_t *uri, const mongoc_ssl_opt_t *ssl_opts, - mongoc_scram_cache_t *scram_cache, mongoc_scram_t *scram /* OUT */); void @@ -284,8 +283,11 @@ _mongoc_topology_scanner_tcp_initiate (mongoc_async_cmd_t *acmd); /* Returns true if versioned server API has been selected, otherwise * false. */ bool -mongoc_topology_scanner_uses_server_api ( - const mongoc_topology_scanner_t *topology_scanner); +mongoc_topology_scanner_uses_server_api (const mongoc_topology_scanner_t *ts); + +/* Returns true if load balancing mode has been selected, otherwise false. */ +bool +mongoc_topology_scanner_uses_loadbalanced (const mongoc_topology_scanner_t *ts); BSON_END_DECLS diff --git a/src/mongoc/mongoc-topology-scanner.c b/src/mongoc/mongoc-topology-scanner.c index 198c6456..f8065b57 100644 --- a/src/mongoc/mongoc-topology-scanner.c +++ b/src/mongoc/mongoc-topology-scanner.c @@ -170,7 +170,6 @@ _mongoc_topology_scanner_add_speculative_authentication ( bson_t *cmd, const mongoc_uri_t *uri, const mongoc_ssl_opt_t *ssl_opts, - mongoc_scram_cache_t *scram_cache, mongoc_scram_t *scram /* OUT */) { bson_t auth_cmd; @@ -204,10 +203,6 @@ _mongoc_topology_scanner_add_speculative_authentication ( _mongoc_uri_init_scram (uri, scram, algo); - if (scram_cache) { - _mongoc_scram_set_cache (scram, scram_cache); - } - if (_mongoc_cluster_get_auth_cmd_scram (algo, scram, &auth_cmd, &error)) { const char *auth_source; @@ -258,40 +253,33 @@ _build_handshake_cmd (const bson_t *basis_cmd, bool is_loadbalanced) { bson_t *doc = bson_copy (basis_cmd); - bson_t subdoc; bson_iter_t iter; - const char *key; - int keylen; const bson_t *compressors; - int count = 0; - char buf[16]; - bool subdoc_okay; + bson_array_builder_t *subarray; BSON_ASSERT (doc); + bson_t *handshake_doc = + _mongoc_handshake_build_doc_with_application (appname); - BSON_APPEND_DOCUMENT_BEGIN (doc, HANDSHAKE_FIELD, &subdoc); - subdoc_okay = - _mongoc_handshake_build_doc_with_application (&subdoc, appname); - bson_append_document_end (doc, &subdoc); - - if (!subdoc_okay) { + if (!handshake_doc) { bson_destroy (doc); return NULL; } + bson_append_document (doc, HANDSHAKE_FIELD, -1, handshake_doc); + bson_destroy (handshake_doc); - BSON_APPEND_ARRAY_BEGIN (doc, "compression", &subdoc); + BSON_APPEND_ARRAY_BUILDER_BEGIN (doc, "compression", &subarray); if (uri) { compressors = mongoc_uri_get_compressors (uri); if (bson_iter_init (&iter, compressors)) { while (bson_iter_next (&iter)) { - keylen = bson_uint32_to_string (count++, &key, buf, sizeof buf); - bson_append_utf8 ( - &subdoc, key, (int) keylen, bson_iter_key (&iter), -1); + bson_array_builder_append_utf8 ( + subarray, bson_iter_key (&iter), -1); } } } - bson_append_array_end (doc, &subdoc); + bson_append_array_builder_end (doc, subarray); if (is_loadbalanced) { BSON_APPEND_BOOL (doc, "loadBalanced", true); @@ -301,13 +289,19 @@ _build_handshake_cmd (const bson_t *basis_cmd, return doc; } +static bool +_should_use_op_msg (const mongoc_topology_scanner_t *ts) +{ + return mongoc_topology_scanner_uses_server_api (ts) || + mongoc_topology_scanner_uses_loadbalanced (ts); +} + const bson_t * _mongoc_topology_scanner_get_monitoring_cmd (mongoc_topology_scanner_t *ts, bool hello_ok) { - return hello_ok || mongoc_topology_scanner_uses_server_api (ts) - ? &ts->hello_cmd - : &ts->legacy_hello_cmd; + return hello_ok || _should_use_op_msg (ts) ? &ts->hello_cmd + : &ts->legacy_hello_cmd; } void @@ -338,12 +332,11 @@ _mongoc_topology_scanner_dup_handshake_cmd (mongoc_topology_scanner_t *ts, /* Construct a new handshake command to be sent */ BSON_ASSERT (ts->handshake_cmd == NULL); bson_mutex_unlock (&ts->handshake_cmd_mtx); - new_cmd = _build_handshake_cmd (mongoc_topology_scanner_uses_server_api (ts) - ? &ts->hello_cmd - : &ts->legacy_hello_cmd, - appname, - ts->uri, - ts->loadbalanced); + new_cmd = _build_handshake_cmd ( + _should_use_op_msg (ts) ? &ts->hello_cmd : &ts->legacy_hello_cmd, + appname, + ts->uri, + ts->loadbalanced); bson_mutex_lock (&ts->handshake_cmd_mtx); if (ts->handshake_state != HANDSHAKE_CMD_UNINITIALIZED) { /* Someone else updated the handshake_cmd while we were building ours. @@ -365,9 +358,8 @@ _mongoc_topology_scanner_dup_handshake_cmd (mongoc_topology_scanner_t *ts, after_init: /* If the doc turned out to be too big */ if (ts->handshake_state == HANDSHAKE_CMD_TOO_BIG) { - bson_t *ret = mongoc_topology_scanner_uses_server_api (ts) - ? &ts->hello_cmd - : &ts->legacy_hello_cmd; + bson_t *ret = + _should_use_op_msg (ts) ? &ts->hello_cmd : &ts->legacy_hello_cmd; bson_copy_to (ret, copy_into); } else { BSON_ASSERT (ts->handshake_cmd != NULL); @@ -385,14 +377,12 @@ _begin_hello_cmd (mongoc_topology_scanner_node_t *node, bool use_handshake) { mongoc_topology_scanner_t *ts = node->ts; - mongoc_opcode_t cmd_opcode_type = MONGOC_OPCODE_QUERY; bson_t cmd; /* If we're asked to use a specific API version, we should send our hello handshake via op_msg rather than the legacy op_query: */ - if (mongoc_topology_scanner_uses_server_api (ts)) { - cmd_opcode_type = MONGOC_OPCODE_MSG; - } + const int32_t cmd_opcode = + _should_use_op_msg (ts) ? MONGOC_OP_CODE_MSG : MONGOC_OP_CODE_QUERY; if (node->last_used != -1 && node->last_failed == -1 && !use_handshake) { /* The node's been used before and not failed recently */ @@ -417,7 +407,7 @@ _begin_hello_cmd (mongoc_topology_scanner_node_t *node, #endif _mongoc_topology_scanner_add_speculative_authentication ( - &cmd, ts->uri, ssl_opts, NULL, &node->scram); + &cmd, ts->uri, ssl_opts, &node->scram); } if (!bson_empty (&ts->cluster_time)) { @@ -437,7 +427,7 @@ _begin_hello_cmd (mongoc_topology_scanner_node_t *node, node->host.host, "admin", &cmd, - cmd_opcode_type, + cmd_opcode, &_async_handler, node, ts->connect_timeout_msec); @@ -601,10 +591,6 @@ mongoc_topology_scanner_node_disconnect (mongoc_topology_scanner_node_t *node, } node->stream = NULL; - memset ( - &node->sasl_supported_mechs, 0, sizeof (node->sasl_supported_mechs)); - node->negotiated_sasl_supported_mechs = false; - bson_reinit (&node->speculative_auth_response); } mongoc_server_description_destroy (node->handshake_sd); node->handshake_sd = NULL; @@ -1094,6 +1080,20 @@ mongoc_topology_scanner_node_setup (mongoc_topology_scanner_node_t *node, BSON_ASSERT (!node->retired); + // If a new stream is needed, reset state authentication state. + // Authentication state is tied to a stream. + { + node->has_auth = false; + bson_reinit (&node->speculative_auth_response); +#ifdef MONGOC_ENABLE_CRYPTO + // Destroy and zero `node->scram`. + _mongoc_scram_destroy (&node->scram); +#endif + memset ( + &node->sasl_supported_mechs, 0, sizeof (node->sasl_supported_mechs)); + node->negotiated_sasl_supported_mechs = false; + } + if (node->ts->initiator) { stream = node->ts->initiator ( node->ts->uri, &node->host, node->ts->initiator_context, error); @@ -1124,8 +1124,6 @@ mongoc_topology_scanner_node_setup (mongoc_topology_scanner_node_t *node, node->ts->setup_err_cb (node->id, node->ts->cb_data, error); return; } - - node->has_auth = false; } /* @@ -1504,8 +1502,15 @@ _mongoc_topology_scanner_set_loadbalanced (mongoc_topology_scanner_t *ts, } bool -mongoc_topology_scanner_uses_server_api ( - const mongoc_topology_scanner_t *topology_scanner) +mongoc_topology_scanner_uses_server_api (const mongoc_topology_scanner_t *ts) { - return NULL != topology_scanner->api; + BSON_ASSERT_PARAM (ts); + return NULL != ts->api; +} + +bool +mongoc_topology_scanner_uses_loadbalanced (const mongoc_topology_scanner_t *ts) +{ + BSON_ASSERT_PARAM (ts); + return ts->loadbalanced; } diff --git a/src/mongoc/mongoc-topology.c b/src/mongoc/mongoc-topology.c index b472c7cf..6b7dc1c3 100644 --- a/src/mongoc/mongoc-topology.c +++ b/src/mongoc/mongoc-topology.c @@ -71,12 +71,12 @@ mongoc_topology_reconcile (const mongoc_topology_t *topology, { mongoc_set_t *servers; mongoc_server_description_t *sd; - int i; mongoc_topology_scanner_node_t *ele, *tmp; + BSON_ASSERT (topology->single_threaded); servers = mc_tpld_servers (td); /* Add newly discovered nodes */ - for (i = 0; i < (int) servers->items_len; i++) { + for (size_t i = 0u; i < servers->items_len; i++) { sd = mongoc_set_get_item (servers, i); _mongoc_topology_reconcile_add_nodes (sd, topology->scanner); } @@ -125,15 +125,16 @@ _mongoc_topology_scanner_setup_err_cb (uint32_t id, { mongoc_topology_t *topology = BSON_ASSERT_PTR_INLINE (data); + BSON_ASSERT (topology->single_threaded); if (_mongoc_topology_get_type (topology) == MONGOC_TOPOLOGY_LOAD_BALANCED) { /* In load balanced mode, scanning is only for connection establishment. * It must not modify the topology description. */ } else { - /* We need to update the topology description */ - mc_tpld_modification mod = mc_tpld_modify_begin (topology); + // Use `mc_tpld_unsafe_get_mutable` to get a mutable topology description + // without locking. This function only applies to single-threaded clients. + mongoc_topology_description_t *td = mc_tpld_unsafe_get_mutable (topology); mongoc_topology_description_handle_hello ( - mod.new_td, id, NULL /* hello reply */, -1 /* rtt_msec */, error); - mc_tpld_modify_commit (mod); + td, id, NULL /* hello reply */, -1 /* rtt_msec */, error); } } @@ -160,51 +161,47 @@ _mongoc_topology_scanner_cb (uint32_t id, { mongoc_topology_t *const topology = BSON_ASSERT_PTR_INLINE (data); mongoc_server_description_t *sd; - mc_tpld_modification tdmod; + mongoc_topology_description_t *td; + BSON_ASSERT (topology->single_threaded); if (_mongoc_topology_get_type (topology) == MONGOC_TOPOLOGY_LOAD_BALANCED) { /* In load balanced mode, scanning is only for connection establishment. * It must not modify the topology description. */ return; } - tdmod = mc_tpld_modify_begin (topology); + // Use `mc_tpld_unsafe_get_mutable` to get a mutable topology description + // without locking. This function only applies to single-threaded clients. + td = mc_tpld_unsafe_get_mutable (topology); - sd = mongoc_topology_description_server_by_id (tdmod.new_td, id, NULL); + sd = mongoc_topology_description_server_by_id (td, id, NULL); if (!hello_response) { /* Server monitoring: When a server check fails due to a network error * (including a network timeout), the client MUST clear its connection * pool for the server */ _mongoc_topology_description_clear_connection_pool ( - tdmod.new_td, id, &kZeroServiceId); + td, id, &kZeroServiceId); } /* Server Discovery and Monitoring Spec: "Once a server is connected, the * client MUST change its type to Unknown only after it has retried the * server once." */ if (!hello_response && sd && sd->type != MONGOC_SERVER_UNKNOWN) { - _mongoc_topology_update_no_lock ( - id, hello_response, rtt_msec, tdmod.new_td, error); + _mongoc_topology_update_no_lock (id, hello_response, rtt_msec, td, error); /* add another hello call to the current scan - the scan continues * until all commands are done */ mongoc_topology_scanner_scan (topology->scanner, sd->id); } else { - _mongoc_topology_update_no_lock ( - id, hello_response, rtt_msec, tdmod.new_td, error); + _mongoc_topology_update_no_lock (id, hello_response, rtt_msec, td, error); /* The processing of the hello results above may have added, changed, or * removed server descriptions. We need to reconcile that with our * monitoring agents */ - mongoc_topology_reconcile (topology, tdmod.new_td); - - mongoc_cond_broadcast (&topology->cond_client); + mongoc_topology_reconcile (topology, td); } - - - mc_tpld_modify_commit (tdmod); } static void @@ -230,10 +227,6 @@ static int _server_session_should_prune (mongoc_server_session_t *session, mongoc_topology_t *topo) { - bool is_loadbalanced; - int timeout; - mc_shared_tpld td; - BSON_ASSERT_PARAM (session); BSON_ASSERT_PARAM (topo); @@ -248,9 +241,9 @@ _server_session_should_prune (mongoc_server_session_t *session, } /* Check for a timeout */ - td = mc_tpld_take_ref (topo); - timeout = td.ptr->session_timeout_minutes; - is_loadbalanced = td.ptr->type == MONGOC_TOPOLOGY_LOAD_BALANCED; + mc_shared_tpld td = mc_tpld_take_ref (topo); + const int64_t timeout = td.ptr->session_timeout_minutes; + const bool is_loadbalanced = td.ptr->type == MONGOC_TOPOLOGY_LOAD_BALANCED; mc_tpld_drop_ref (&td); /** Load balanced topology sessions never expire */ @@ -271,32 +264,29 @@ _tpld_destroy_and_free (void *tpl_descr) const mongoc_host_list_t ** _mongoc_apply_srv_max_hosts (const mongoc_host_list_t *hl, - const int32_t max_hosts, - size_t *const hl_array_size) + size_t max_hosts, + size_t *hl_array_size) { - size_t hl_size; - size_t idx; const mongoc_host_list_t **hl_array; - BSON_ASSERT (max_hosts >= 0); BSON_ASSERT_PARAM (hl_array_size); - hl_size = (size_t) _mongoc_host_list_length (hl); + const size_t hl_size = _mongoc_host_list_length (hl); - if (hl_size == 0) { - *hl_array_size = 0; + if (hl_size == 0u) { + *hl_array_size = 0u; return NULL; } hl_array = bson_malloc (hl_size * sizeof (mongoc_host_list_t *)); - for (idx = 0u; hl; hl = hl->next) { + for (size_t idx = 0u; hl; hl = hl->next) { hl_array[idx++] = hl; } - if (max_hosts == 0 || /* Unlimited. */ - hl_size == 1u || /* Trivial case. */ - hl_size <= (size_t) max_hosts /* Already satisfies limit. */ + if (max_hosts == 0u || // Unlimited. + hl_size == 1u || // Trivial case. + hl_size <= max_hosts // Already satisfies limit. ) { /* No random shuffle or selection required. */ *hl_array_size = hl_size; @@ -307,7 +297,7 @@ _mongoc_apply_srv_max_hosts (const mongoc_host_list_t *hl, * and less than the number of hosts in the DNS result, the driver MUST * randomly select that many hosts and use them to populate the seedlist. * Drivers SHOULD use the `Fisher-Yates shuffle` for randomization. */ - for (idx = hl_size - 1u; idx > 0u; --idx) { + for (size_t idx = hl_size - 1u; idx > 0u; --idx) { /* 0 <= swap_pos <= idx */ const size_t swap_pos = _mongoc_rand_size_t (0u, idx, _mongoc_simple_rand_size_t); @@ -322,6 +312,58 @@ _mongoc_apply_srv_max_hosts (const mongoc_host_list_t *hl, return hl_array; } +// `_detect_nongenuine_host` logs if the host string suggests use of CosmosDB or +// DocumentDB. See DRIVERS-2583 for behavior requirements. Returns true if a +// CosmosDB or DocumentDB host is detected. +static bool +_detect_nongenuine_host (const char *host) +{ + char *const host_lowercase = bson_strdup (host); + + mongoc_lowercase (host, host_lowercase); + + if (mongoc_ends_with (host_lowercase, ".cosmos.azure.com")) { + MONGOC_INFO ( + "You appear to be connected to a CosmosDB cluster. For more " + "information regarding feature compatibility and support please " + "visit https://www.mongodb.com/supportability/cosmosdb"); + bson_free (host_lowercase); + return true; + } + + if (mongoc_ends_with (host_lowercase, ".docdb.amazonaws.com") || + mongoc_ends_with (host_lowercase, ".docdb-elastic.amazonaws.com")) { + MONGOC_INFO ( + "You appear to be connected to a DocumentDB cluster. For more " + "information regarding feature compatibility and support please " + "visit https://www.mongodb.com/supportability/documentdb"); + bson_free (host_lowercase); + return true; + } + + bson_free (host_lowercase); + return false; +} + +static void +_detect_nongenuine_hosts (const mongoc_uri_t *uri) +{ + const char *srv_hostname = mongoc_uri_get_srv_hostname (uri); + if (srv_hostname) { + _detect_nongenuine_host (srv_hostname); + return; + } + + const mongoc_host_list_t *iter; + + LL_FOREACH (mongoc_uri_get_hosts (uri), iter) + { + if (_detect_nongenuine_host (iter->host)) { + return; + } + } +} + /* *------------------------------------------------------------------------- * @@ -340,8 +382,6 @@ _mongoc_apply_srv_max_hosts (const mongoc_host_list_t *hl, mongoc_topology_t * mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded) { - int64_t heartbeat_default; - int64_t heartbeat; mongoc_topology_t *topology; mongoc_topology_description_type_t init_type; mongoc_topology_description_t *td; @@ -353,6 +393,8 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded) BSON_ASSERT (uri); + _detect_nongenuine_hosts (uri); + #ifndef MONGOC_ENABLE_CRYPTO if (mongoc_uri_get_option_as_bool ( uri, MONGOC_URI_RETRYWRITES, MONGOC_DEFAULT_RETRYWRITES)) { @@ -363,6 +405,7 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded) #endif topology = (mongoc_topology_t *) bson_malloc0 (sizeof *topology); + topology->usleep_fn = mongoc_usleep_default_impl; topology->session_pool = mongoc_server_session_pool_new_with_params (_server_session_init, _server_session_destroy, @@ -370,11 +413,12 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded) topology); topology->valid = false; - heartbeat_default = + + const int32_t heartbeat_default = single_threaded ? MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED : MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED; - heartbeat = mongoc_uri_get_option_as_int32 ( + const int32_t heartbeat = mongoc_uri_get_option_as_int32 ( uri, MONGOC_URI_HEARTBEATFREQUENCYMS, heartbeat_default); topology->_shared_descr_._sptr_ = mongoc_shared_ptr_create ( @@ -523,6 +567,10 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded) td->max_hosts = mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_SRVMAXHOSTS, 0); + if (td->max_hosts < 0) { + topology->valid = false; + } + /* * Set topology type from URI: * + if directConnection=true @@ -596,24 +644,23 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded) return topology; } - { - size_t idx = 0u; - size_t hl_array_size = 0u; - uint32_t id = 0u; + size_t hl_array_size = 0u; - const mongoc_host_list_t *const *hl_array = - _mongoc_apply_srv_max_hosts (hl, td->max_hosts, &hl_array_size); + BSON_ASSERT (bson_in_range_signed (size_t, td->max_hosts)); + const mongoc_host_list_t *const *hl_array = + _mongoc_apply_srv_max_hosts (hl, (size_t) td->max_hosts, &hl_array_size); - for (idx = 0u; idx < hl_array_size; ++idx) { - const mongoc_host_list_t *const elem = hl_array[idx]; + for (size_t idx = 0u; idx < hl_array_size; ++idx) { + const mongoc_host_list_t *const elem = hl_array[idx]; - mongoc_topology_description_add_server (td, elem->host_and_port, &id); - mongoc_topology_scanner_add (topology->scanner, elem, id, false); - } + uint32_t id = 0u; - bson_free ((void *) hl_array); + mongoc_topology_description_add_server (td, elem->host_and_port, &id); + mongoc_topology_scanner_add (topology->scanner, elem, id, false); } + bson_free ((void *) hl_array); + return topology; } @@ -887,7 +934,8 @@ mongoc_topology_rescan_srv (mongoc_topology_t *topology) static void mongoc_topology_scan_once (mongoc_topology_t *topology, bool obey_cooldown) { - mc_tpld_modification tdmod; + mongoc_topology_description_t *td; + BSON_ASSERT (topology->single_threaded); if (mongoc_topology_should_rescan_srv (topology)) { /* Prior to scanning hosts, update the list of SRV hosts, if applicable. */ @@ -898,9 +946,10 @@ mongoc_topology_scan_once (mongoc_topology_t *topology, bool obey_cooldown) * description based on hello responses in connection handshakes, see * _mongoc_topology_update_from_handshake. retire scanner nodes for removed * members and create scanner nodes for new ones. */ - tdmod = mc_tpld_modify_begin (topology); - mongoc_topology_reconcile (topology, tdmod.new_td); - mc_tpld_modify_commit (tdmod); + // Use `mc_tpld_unsafe_get_mutable` to get a mutable topology description + // without locking. This function only applies to single-threaded clients. + td = mc_tpld_unsafe_get_mutable (topology); + mongoc_topology_reconcile (topology, td); mongoc_topology_scanner_start (topology->scanner, obey_cooldown); mongoc_topology_scanner_work (topology->scanner); @@ -926,6 +975,7 @@ void _mongoc_topology_do_blocking_scan (mongoc_topology_t *topology, bson_error_t *error) { + BSON_ASSERT (topology->single_threaded); _mongoc_handshake_freeze (); mongoc_topology_scan_once (topology, true /* obey cooldown */); @@ -938,9 +988,6 @@ mongoc_topology_compatible (const mongoc_topology_description_t *td, const mongoc_read_prefs_t *read_prefs, bson_error_t *error) { - int64_t max_staleness_seconds; - int32_t max_wire_version; - if (td->compatibility_error.code) { if (error) { memcpy (error, &td->compatibility_error, sizeof (bson_error_t)); @@ -953,21 +1000,10 @@ mongoc_topology_compatible (const mongoc_topology_description_t *td, return true; } - max_staleness_seconds = + const int64_t max_staleness_seconds = mongoc_read_prefs_get_max_staleness_seconds (read_prefs); if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) { - max_wire_version = - mongoc_topology_description_lowest_max_wire_version (td); - - if (max_wire_version < WIRE_VERSION_MAX_STALENESS) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "Not all servers support maxStalenessSeconds"); - return false; - } - /* shouldn't happen if we've properly enforced wire version */ if (!mongoc_topology_description_all_sds_have_write_date (td)) { bson_set_error (error, @@ -1017,7 +1053,7 @@ mongoc_topology_select (mongoc_topology_t *topology, bson_error_t *error) { uint32_t server_id = mongoc_topology_select_server_id ( - topology, optype, read_prefs, must_use_primary, error); + topology, optype, read_prefs, must_use_primary, NULL, error); if (server_id) { /* new copy of the server description */ @@ -1062,6 +1098,7 @@ _mongoc_topology_select_server_id_loadbalanced (mongoc_topology_t *topology, MONGOC_SS_WRITE, NULL /* read prefs */, NULL /* chosen read mode */, + NULL /* deprioritized servers */, 0 /* local threshold */); if (!selected_server) { @@ -1130,6 +1167,7 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_prefs, bool *must_use_primary, + const mongoc_deprioritized_servers_t *ds, bson_error_t *error) { static const char *timeout_msg = @@ -1182,9 +1220,11 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology, if (topology->single_threaded) { if (!td.ptr->opened) { - mc_tpld_modification tdmod = mc_tpld_modify_begin (topology); - _mongoc_topology_description_monitor_opening (tdmod.new_td); - mc_tpld_modify_commit (tdmod); + // Use `mc_tpld_unsafe_get_mutable` to get a mutable topology + // description without locking. This block only applies to + // single-threaded clients. + _mongoc_topology_description_monitor_opening ( + mc_tpld_unsafe_get_mutable (topology)); mc_tpld_renew_ref (&td, topology); } @@ -1226,8 +1266,7 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology, server_id = 0; goto done; } - - _mongoc_usleep (sleep_usec); + topology->usleep_fn (sleep_usec, topology->usleep_data); } /* takes up to connectTimeoutMS. sets "last_scan", clears "stale" */ @@ -1244,8 +1283,13 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology, goto done; } - selected_server = mongoc_topology_description_select ( - td.ptr, optype, read_prefs, must_use_primary, local_threshold_ms); + selected_server = + mongoc_topology_description_select (td.ptr, + optype, + read_prefs, + must_use_primary, + ds, + local_threshold_ms); if (selected_server) { server_id = selected_server->id; @@ -1291,7 +1335,7 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology, } selected_server = mongoc_topology_description_select ( - td.ptr, optype, read_prefs, must_use_primary, local_threshold_ms); + td.ptr, optype, read_prefs, must_use_primary, ds, local_threshold_ms); if (selected_server) { server_id = selected_server->id; @@ -1307,7 +1351,7 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology, * occurred while we were waiting on the lock. */ mc_tpld_renew_ref (&td, topology); selected_server = mongoc_topology_description_select ( - td.ptr, optype, read_prefs, must_use_primary, local_threshold_ms); + td.ptr, optype, read_prefs, must_use_primary, ds, local_threshold_ms); if (selected_server) { server_id = selected_server->id; bson_mutex_unlock (&topology->tpld_modification_mtx); @@ -1576,11 +1620,13 @@ _mongoc_topology_pop_server_session (mongoc_topology_t *topology, if (!loadbalanced && timeout == MONGOC_NO_SESSIONS) { /* if needed, connect and check for session timeout again */ if (!mongoc_topology_description_has_data_node (td.ptr)) { - if (!mongoc_topology_select_server_id (topology, - MONGOC_SS_READ, - NULL /* read prefs */, - NULL /* chosen read mode */, - error)) { + if (!mongoc_topology_select_server_id ( + topology, + MONGOC_SS_READ, + NULL /* read prefs */, + NULL /* chosen read mode */, + NULL /* deprioritized servers */, + error)) { ss = NULL; goto done; } @@ -1666,7 +1712,7 @@ _mongoc_topology_push_server_session (mongoc_topology_t *topology, bool _mongoc_topology_end_sessions_cmd (mongoc_topology_t *topology, bson_t *cmd) { - bson_t ar; + bson_array_builder_t *ar; /* Only end up to 10'000 sessions */ const int ENDED_SESSION_PRUNING_LIMIT = 10000; int i = 0; @@ -1674,15 +1720,12 @@ _mongoc_topology_end_sessions_cmd (mongoc_topology_t *topology, bson_t *cmd) mongoc_server_session_pool_get_existing (topology->session_pool); bson_init (cmd); - BSON_APPEND_ARRAY_BEGIN (cmd, "endSessions", &ar); + BSON_APPEND_ARRAY_BUILDER_BEGIN (cmd, "endSessions", &ar); for (; i < ENDED_SESSION_PRUNING_LIMIT && ss != NULL; ++i, ss = mongoc_server_session_pool_get_existing (topology->session_pool)) { - char buf[16]; - const char *key; - bson_uint32_to_string (i, &key, buf, sizeof buf); - BSON_APPEND_DOCUMENT (&ar, key, &ss->lsid); + bson_array_builder_append_document (ar, &ss->lsid); mongoc_server_session_pool_drop (topology->session_pool, ss); } @@ -1692,7 +1735,7 @@ _mongoc_topology_end_sessions_cmd (mongoc_topology_t *topology, bson_t *cmd) mongoc_server_session_pool_return (topology->session_pool, ss); } - bson_append_array_end (cmd, &ar); + bson_append_array_builder_end (cmd, ar); return i > 0; } @@ -1724,7 +1767,7 @@ _find_topology_version (const bson_t *reply, bson_t *topology_version) return; } bson_iter_document (&iter, &len, &bytes); - bson_init_static (topology_version, bytes, len); + BSON_ASSERT (bson_init_static (topology_version, bytes, len)); } @@ -1944,12 +1987,11 @@ _topology_collect_errors (const mongoc_topology_description_t *td, { const mongoc_server_description_t *server_description; bson_string_t *error_message; - int i; memset (error_out, 0, sizeof (bson_error_t)); error_message = bson_string_new (""); - for (i = 0; i < mc_tpld_servers_const (td)->items_len; i++) { + for (size_t i = 0u; i < mc_tpld_servers_const (td)->items_len; i++) { const bson_error_t *error; server_description = mc_tpld_servers_const (td)->items[i].item; @@ -2045,5 +2087,13 @@ mc_tpld_modify_drop (mc_tpld_modification mod) bool mongoc_topology_uses_server_api (const mongoc_topology_t *topology) { + BSON_ASSERT_PARAM (topology); return mongoc_topology_scanner_uses_server_api (topology->scanner); } + +bool +mongoc_topology_uses_loadbalanced (const mongoc_topology_t *topology) +{ + BSON_ASSERT_PARAM (topology); + return mongoc_topology_scanner_uses_loadbalanced (topology->scanner); +} diff --git a/src/mongoc/mongoc-uri.c b/src/mongoc/mongoc-uri.c index 06669802..bf3ed673 100644 --- a/src/mongoc/mongoc-uri.c +++ b/src/mongoc/mongoc-uri.c @@ -37,6 +37,8 @@ #include "mongoc-compression-private.h" #include "utlist.h" +#include + struct _mongoc_uri_t { char *str; bool is_srv; @@ -82,9 +84,6 @@ _mongoc_uri_set_option_as_int64_with_error (mongoc_uri_t *uri, int64_t value, bson_error_t *error); -static bool -ends_with (const char *str, const char *suffix); - static void mongoc_uri_do_unescape (char **str) { @@ -166,7 +165,7 @@ mongoc_uri_validate_srv_result (const mongoc_uri_t *uri, VALIDATE_SRV_ERR (); } - if (!ends_with (host, srv_host)) { + if (!mongoc_ends_with (host, srv_host)) { VALIDATE_SRV_ERR (); } @@ -281,41 +280,6 @@ scan_to_unichar (const char *str, } -/* - *-------------------------------------------------------------------------- - * - * ends_with -- - * - * Return true if str ends with suffix. - * - *-------------------------------------------------------------------------- - */ -static bool -ends_with (const char *str, const char *suffix) -{ - size_t str_len = strlen (str); - size_t suffix_len = strlen (suffix); - const char *s1, *s2; - - if (str_len < suffix_len) { - return false; - } - - /* start at the ends of both strings */ - s1 = str + str_len; - s2 = suffix + suffix_len; - - /* until either pointer reaches start of its string, compare the pointers */ - for (; s1 >= str && s2 >= suffix; s1--, s2--) { - if (*s1 != *s2) { - return false; - } - } - - return true; -} - - static bool mongoc_uri_parse_scheme (mongoc_uri_t *uri, const char *str, const char **end) { @@ -1572,6 +1536,8 @@ mongoc_uri_parse_before_slash (mongoc_uri_t *uri, static bool mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error) { + BSON_ASSERT_PARAM (str); + char *before_slash = NULL; const char *tmp; @@ -1600,6 +1566,8 @@ mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error) goto error; } + BSON_ASSERT (str); + if (*str) { if (*str == '/') { str++; @@ -1736,71 +1704,62 @@ bool mongoc_uri_set_mechanism_properties (mongoc_uri_t *uri, const bson_t *properties) { - bson_iter_t iter; - bson_t tmp = BSON_INITIALIZER; - bool r; - BSON_ASSERT (uri); BSON_ASSERT (properties); - if (bson_iter_init_find ( - &iter, &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES)) { - /* copy all elements to tmp besides authMechanismProperties */ - bson_copy_to_excluding_noinit (&uri->credentials, - &tmp, - MONGOC_URI_AUTHMECHANISMPROPERTIES, - (char *) NULL); - - r = BSON_APPEND_DOCUMENT ( - &tmp, MONGOC_URI_AUTHMECHANISMPROPERTIES, properties); - if (!r) { - bson_destroy (&tmp); - return false; - } - - bson_destroy (&uri->credentials); - bson_copy_to (&tmp, &uri->credentials); - bson_destroy (&tmp); - - return true; - } else { - bson_destroy (&tmp); - return BSON_APPEND_DOCUMENT ( - &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES, properties); - } + bson_t tmp = BSON_INITIALIZER; + bsonBuildAppend ( + tmp, + // Copy the existing credentials, dropping the existing properties if + // present + insert (uri->credentials, not(key (MONGOC_URI_AUTHMECHANISMPROPERTIES))), + // Append the new properties + kv (MONGOC_URI_AUTHMECHANISMPROPERTIES, bson (*properties))); + bson_reinit (&uri->credentials); + bsonBuildAppend (uri->credentials, insert (tmp, true)); + bson_destroy (&tmp); + return bsonBuildError == NULL; } static bool _mongoc_uri_assign_read_prefs_mode (mongoc_uri_t *uri, bson_error_t *error) { - const char *str; - bson_iter_t iter; - BSON_ASSERT (uri); - if (bson_iter_init_find_case ( - &iter, &uri->options, MONGOC_URI_READPREFERENCE) && - BSON_ITER_HOLDS_UTF8 (&iter)) { - str = bson_iter_utf8 (&iter, NULL); - - if (0 == strcasecmp ("primary", str)) { - mongoc_read_prefs_set_mode (uri->read_prefs, MONGOC_READ_PRIMARY); - } else if (0 == strcasecmp ("primarypreferred", str)) { - mongoc_read_prefs_set_mode (uri->read_prefs, - MONGOC_READ_PRIMARY_PREFERRED); - } else if (0 == strcasecmp ("secondary", str)) { - mongoc_read_prefs_set_mode (uri->read_prefs, MONGOC_READ_SECONDARY); - } else if (0 == strcasecmp ("secondarypreferred", str)) { - mongoc_read_prefs_set_mode (uri->read_prefs, - MONGOC_READ_SECONDARY_PREFERRED); - } else if (0 == strcasecmp ("nearest", str)) { - mongoc_read_prefs_set_mode (uri->read_prefs, MONGOC_READ_NEAREST); - } else { + mongoc_read_mode_t mode = 0; + const char *pref = NULL; + bsonParse ( + uri->options, + find ( + // Find the 'readPreference' string + iKeyWithType (MONGOC_URI_READPREFERENCE, utf8), + case ( // Switch on the string content: + when (iStrEqual ("primary"), do(mode = MONGOC_READ_PRIMARY)), + when (iStrEqual ("primaryPreferred"), + do(mode = MONGOC_READ_PRIMARY_PREFERRED)), + when (iStrEqual ("secondary"), do(mode = MONGOC_READ_SECONDARY)), + when (iStrEqual ("secondaryPreferred"), + do(mode = MONGOC_READ_SECONDARY_PREFERRED)), + when (iStrEqual ("nearest"), do(mode = MONGOC_READ_NEAREST)), + else(do({ + pref = bsonAs (cstr); + bsonParseError = "Unsupported readPreference value"; + }))))); + + if (bsonParseError) { + const char *prefix = "Error while assigning URI read preference"; + if (pref) { MONGOC_URI_ERROR ( - error, "Unsupported readPreference value [readPreference=%s]", str); - return false; + error, "%s: %s [readPreference=%s]", prefix, bsonParseError, pref); + } else { + MONGOC_URI_ERROR (error, "%s: %s", prefix, bsonParseError); } + return false; + } + + if (mode != 0) { + mongoc_read_prefs_set_mode (uri->read_prefs, mode); } return true; } @@ -1810,21 +1769,24 @@ static bool _mongoc_uri_build_write_concern (mongoc_uri_t *uri, bson_error_t *error) { mongoc_write_concern_t *write_concern; - const char *str; - bson_iter_t iter; int64_t wtimeoutms; - int value; BSON_ASSERT (uri); write_concern = mongoc_write_concern_new (); uri->write_concern = write_concern; - if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_SAFE) && - BSON_ITER_HOLDS_BOOL (&iter)) { - mongoc_write_concern_set_w ( - write_concern, - bson_iter_bool (&iter) ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); + bsonParse ( + uri->options, + find (iKeyWithType (MONGOC_URI_SAFE, bool), + do(mongoc_write_concern_set_w ( + write_concern, + bsonAs (bool) ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED)))); + + if (bsonParseError) { + MONGOC_URI_ERROR ( + error, "Error while parsing 'safe' URI option: %s", bsonParseError); + return false; } wtimeoutms = mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 0); @@ -1836,48 +1798,61 @@ _mongoc_uri_build_write_concern (mongoc_uri_t *uri, bson_error_t *error) mongoc_write_concern_set_wtimeout_int64 (write_concern, wtimeoutms); } - if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_JOURNAL) && - BSON_ITER_HOLDS_BOOL (&iter)) { - mongoc_write_concern_set_journal (write_concern, bson_iter_bool (&iter)); + bsonParse (uri->options, + find (iKeyWithType (MONGOC_URI_JOURNAL, bool), + do(mongoc_write_concern_set_journal (write_concern, + bsonAs (bool))))); + if (bsonParseError) { + MONGOC_URI_ERROR ( + error, "Error while parsing 'journal' URI option: %s", bsonParseError); + return false; } - if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_W)) { - if (BSON_ITER_HOLDS_INT32 (&iter)) { - value = bson_iter_int32 (&iter); - - switch (value) { - case MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED: - case MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED: - if (mongoc_write_concern_get_journal (write_concern)) { - MONGOC_URI_ERROR ( - error, "Journal conflicts with w value [w=%d]", value); - return false; - } - mongoc_write_concern_set_w (write_concern, value); - break; - default: - if (value > 0) { - mongoc_write_concern_set_w (write_concern, value); - break; - } - MONGOC_URI_ERROR (error, "Unsupported w value [w=%d]", value); - return false; - } - } else if (BSON_ITER_HOLDS_UTF8 (&iter)) { - str = bson_iter_utf8 (&iter, NULL); - - if (0 == strcasecmp ("majority", str)) { - mongoc_write_concern_set_w (write_concern, - MONGOC_WRITE_CONCERN_W_MAJORITY); - } else { - mongoc_write_concern_set_wtag (write_concern, str); - } + int w_int = INT_MAX; + const char *w_str = NULL; + bsonParse ( + uri->options, + find ( + iKey ("w"), // + storeInt32 (w_int), + storeStrRef (w_str), + case ( + // Special W options: + when ( + anyOf (eq (int32, MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED), + eq (int32, MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED)), + // These conflict with journalling: + if (eval (mongoc_write_concern_get_journal (write_concern)), + then (error ("Journal conflicts with w value"))), + do(mongoc_write_concern_set_w (write_concern, bsonAs (int32)))), + // Other positive 'w' value: + when ( + allOf (type (int32), eval (bsonAs (int32) > 0)), + do(mongoc_write_concern_set_w (write_concern, bsonAs (int32)))), + // Special "majority" string: + when (iStrEqual ("majority"), + do(mongoc_write_concern_set_w ( + write_concern, MONGOC_WRITE_CONCERN_W_MAJORITY))), + // Other string: + when (type (utf8), + do(mongoc_write_concern_set_wtag (write_concern, + bsonAs (cstr)))), + // Invalid value: + else(error ("Unsupported w value"))))); + + if (bsonParseError) { + const char *const prefix = "Error while parsing the 'w' URI option"; + if (w_str) { + MONGOC_URI_ERROR ( + error, "%s: %s [w=%s]", prefix, bsonParseError, w_str); + } else if (w_int != INT_MAX) { + MONGOC_URI_ERROR ( + error, "%s: %s [w=%d]", prefix, bsonParseError, w_int); } else { - BSON_ASSERT (false); - return false; + MONGOC_URI_ERROR (error, "%s: %s", prefix, bsonParseError); } + return false; } - return true; } diff --git a/src/mongoc/mongoc-util-private.h b/src/mongoc/mongoc-util-private.h index 9bef65a6..19517104 100644 --- a/src/mongoc/mongoc-util-private.h +++ b/src/mongoc/mongoc-util-private.h @@ -125,6 +125,9 @@ _mongoc_validate_update (const bson_t *update, bson_validate_flags_t vflags, bson_error_t *error); +bool +mongoc_ends_with (const char *str, const char *suffix); + void mongoc_lowercase (const char *src, char *buf /* OUT */); @@ -138,8 +141,8 @@ void _mongoc_bson_array_copy_labels_to (const bson_t *reply, bson_t *dst); void -_mongoc_bson_init_with_transient_txn_error (const mongoc_client_session_t *cs, - bson_t *reply); +_mongoc_add_transient_txn_error (const mongoc_client_session_t *cs, + bson_t *reply); bool _mongoc_document_is_pipeline (const bson_t *document); @@ -162,6 +165,33 @@ _mongoc_document_is_pipeline (const bson_t *document); char * _mongoc_getenv (const char *name); +/* + *-------------------------------------------------------------------------- + * + * _mongoc_setenv -- + * + * Set or overwrite the value of an environment variable. + * + * Returns: + * False if setting the variable was unsuccessful. + * + *-------------------------------------------------------------------------- + */ +bool +_mongoc_setenv (const char *name, const char *value); + +void +bson_copy_to_including_noinit (const bson_t *src, + bson_t *dst, + const char *first_include, + ...) BSON_GNUC_NULL_TERMINATED; + +void +bson_copy_to_including_noinit_va (const bson_t *src, + bson_t *dst, + const char *first_include, + va_list args); + /* Returns a uniformly-distributed uint32_t generated using * `_mongoc_rand_bytes()` if a source of cryptographic randomness is available * (defined only if `MONGOC_ENABLE_CRYPTO` is defined). @@ -241,6 +271,12 @@ _mongoc_iter_document_as_bson (const bson_iter_t *iter, bson_t *bson, bson_error_t *error); +uint8_t * +hex_to_bin (const char *hex, uint32_t *len); + +char * +bin_to_hex (const uint8_t *bin, uint32_t len); + BSON_END_DECLS #endif /* MONGOC_UTIL_PRIVATE_H */ diff --git a/src/mongoc/mongoc-util.c b/src/mongoc/mongoc-util.c index 61227e39..73fe534a 100644 --- a/src/mongoc/mongoc-util.c +++ b/src/mongoc/mongoc-util.c @@ -27,8 +27,10 @@ #include "mongoc-rand-private.h" #include "mongoc-util-private.h" #include "mongoc-client.h" +#include "mongoc-client-private.h" // WIRE_VERSION_* macros. #include "mongoc-client-session-private.h" #include "mongoc-trace-private.h" +#include "mongoc-sleep.h" const bson_validate_flags_t _mongoc_default_insert_vflags = BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | @@ -83,10 +85,20 @@ _mongoc_hex_md5 (const char *input) return bson_strdup (digest_str); } +void +mongoc_client_set_usleep_impl (mongoc_client_t *client, + mongoc_usleep_func_t usleep_func, + void *user_data) +{ + client->topology->usleep_fn = usleep_func; + client->topology->usleep_data = user_data; +} void -_mongoc_usleep (int64_t usec) +mongoc_usleep_default_impl (int64_t usec, void *user_data) { + BSON_UNUSED (user_data); + #ifdef _WIN32 LARGE_INTEGER ft; HANDLE timer; @@ -104,6 +116,13 @@ _mongoc_usleep (int64_t usec) #endif } +void +_mongoc_usleep (int64_t usec) +{ + mongoc_usleep_default_impl (usec, NULL); +} + + int64_t _mongoc_get_real_time_ms (void) { @@ -288,28 +307,30 @@ _mongoc_wire_version_to_server_version (int32_t version) return "3.4"; case 6: return "3.6"; - case 7: + case WIRE_VERSION_4_0: return "4.0"; - case 8: + case WIRE_VERSION_4_2: return "4.2"; - case 9: + case WIRE_VERSION_4_4: return "4.4"; case 10: return "4.7"; case 11: return "4.8"; - case 12: + case WIRE_VERSION_4_9: return "4.9"; - case 13: + case WIRE_VERSION_5_0: return "5.0"; - case 14: + case WIRE_VERSION_5_1: return "5.1"; case 15: return "5.2"; case 16: return "5.3"; - case 17: + case WIRE_VERSION_6_0: return "6.0"; + case WIRE_VERSION_7_0: + return "7.0"; default: return "Unknown"; } @@ -477,6 +498,97 @@ _mongoc_validate_update (const bson_t *update, return true; } + +static bool +should_include (const char *first_include, va_list args, const char *name) +{ + bool ret = false; + const char *include = first_include; + va_list args_copy; + + va_copy (args_copy, args); + + do { + if (!strcmp (name, include)) { + ret = true; + break; + } + } while ((include = va_arg (args_copy, const char *))); + + va_end (args_copy); + + return ret; +} + + +void +bson_copy_to_including_noinit_va (const bson_t *src, + bson_t *dst, + const char *first_include, + va_list args) +{ + BSON_ASSERT_PARAM (src); + BSON_ASSERT_PARAM (dst); + BSON_ASSERT_PARAM (first_include); + bson_iter_t iter; + + if (bson_iter_init (&iter, src)) { + while (bson_iter_next (&iter)) { + if (should_include (first_include, args, bson_iter_key (&iter))) { + if (!bson_append_iter (dst, NULL, 0, &iter)) { + /* + * This should not be able to happen since we are copying + * from within a valid bson_t. + */ + BSON_ASSERT (false); + return; + } + } + } + } +} + +void +bson_copy_to_including_noinit (const bson_t *src, + bson_t *dst, + const char *first_include, + ...) +{ + BSON_ASSERT_PARAM (src); + BSON_ASSERT_PARAM (dst); + BSON_ASSERT_PARAM (first_include); + + va_list args; + va_start (args, first_include); + bson_copy_to_including_noinit_va (src, dst, first_include, args); + va_end (args); +} + +/* + *-------------------------------------------------------------------------- + * + * mongoc_ends_with -- + * + * Return true if str ends with suffix. + * + *-------------------------------------------------------------------------- + */ +bool +mongoc_ends_with (const char *str, const char *suffix) +{ + BSON_ASSERT_PARAM (str); + BSON_ASSERT_PARAM (suffix); + + const size_t str_len = strlen (str); + const size_t suffix_len = strlen (suffix); + + if (str_len < suffix_len) { + return false; + } + + return strcmp (str + (str_len - suffix_len), suffix) == 0; +} + void mongoc_lowercase (const char *src, char *buf /* OUT */) { @@ -576,10 +688,10 @@ _mongoc_bson_array_copy_labels_to (const bson_t *reply, bson_t *dst) /*-------------------------------------------------------------------------- * - * _mongoc_bson_init_with_transient_txn_error -- + * _mongoc_add_transient_txn_error -- * - * If @reply is not NULL, initialize it. If @cs is not NULL and in a - * transaction, add errorLabels: ["TransientTransactionError"] to @cs. + * If @cs is not NULL and in a transaction, add errorLabels: + * ["TransientTransactionError"] to @reply. * * Transactions Spec: TransientTransactionError includes "server * selection error encountered running any command besides @@ -594,21 +706,27 @@ _mongoc_bson_array_copy_labels_to (const bson_t *reply, bson_t *dst) */ void -_mongoc_bson_init_with_transient_txn_error (const mongoc_client_session_t *cs, - bson_t *reply) +_mongoc_add_transient_txn_error (const mongoc_client_session_t *cs, + bson_t *reply) { - bson_t labels; - if (!reply) { return; } - bson_init (reply); - if (_mongoc_client_session_in_txn (cs)) { - BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels); - BSON_APPEND_UTF8 (&labels, "0", TRANSIENT_TXN_ERR); - bson_append_array_end (reply, &labels); + bson_t labels = BSON_INITIALIZER; + _mongoc_bson_array_copy_labels_to (reply, &labels); + _mongoc_bson_array_add_label (&labels, TRANSIENT_TXN_ERR); + + bson_t new_reply = BSON_INITIALIZER; + bson_copy_to_excluding_noinit (reply, &new_reply, "errorLabels", NULL); + BSON_APPEND_ARRAY (&new_reply, "errorLabels", &labels); + + bson_reinit (reply); + bson_concat (reply, &new_reply); + + bson_destroy (&labels); + bson_destroy (&new_reply); } } @@ -669,9 +787,9 @@ _mongoc_getenv (const char *name) return NULL; } #else - - if (getenv (name) && strlen (getenv (name))) { - return bson_strdup (getenv (name)); + char *const var = getenv (name); + if (var && strlen (var)) { + return bson_strdup (var); } else { return NULL; } @@ -679,6 +797,22 @@ _mongoc_getenv (const char *name) #endif } +bool +_mongoc_setenv (const char *name, const char *value) +{ +#ifdef _WIN32 + return SetEnvironmentVariableA (name, value) != 0; +#else + + if (0 != setenv (name, value, 1)) { + return false; + } + + return true; +#endif +} + + /* Nearly Divisionless (Algorithm 5): https://arxiv.org/abs/1805.10941 */ static uint32_t _mongoc_rand_nduid32 (uint32_t s, uint32_t (*rand32) (void)) @@ -897,3 +1031,44 @@ _mongoc_iter_document_as_bson (const bson_iter_t *iter, return true; } + +uint8_t * +hex_to_bin (const char *hex, uint32_t *len) +{ + uint8_t *out; + + const size_t hex_len = strlen (hex); + if (hex_len % 2u != 0u) { + return NULL; + } + + BSON_ASSERT (bson_in_range_unsigned (uint32_t, hex_len / 2u)); + + *len = (uint32_t) (hex_len / 2u); + out = bson_malloc0 (*len); + + for (uint32_t i = 0; i < hex_len; i += 2u) { + uint32_t hex_char; + + if (1 != sscanf (hex + i, "%2x", &hex_char)) { + bson_free (out); + return NULL; + } + + BSON_ASSERT (bson_in_range_unsigned (uint8_t, hex_char)); + out[i / 2u] = (uint8_t) hex_char; + } + return out; +} + +char * +bin_to_hex (const uint8_t *bin, uint32_t len) +{ + char *out = bson_malloc0 (2u * len + 1u); + + for (uint32_t i = 0u; i < len; i++) { + bson_snprintf (out + (2u * i), 3, "%02x", bin[i]); + } + + return out; +} diff --git a/src/mongoc/mongoc-version.h b/src/mongoc/mongoc-version.h index 3aa655fc..39181741 100644 --- a/src/mongoc/mongoc-version.h +++ b/src/mongoc/mongoc-version.h @@ -15,10 +15,11 @@ */ -#if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) +#if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif +// clang-format off #ifndef MONGOC_VERSION_H #define MONGOC_VERSION_H @@ -37,7 +38,7 @@ * * MONGOC minor version component (e.g. 2 if %MONGOC_VERSION is 1.2.3) */ -#define MONGOC_MINOR_VERSION (23) +#define MONGOC_MINOR_VERSION (26) /** @@ -53,7 +54,7 @@ * * MONGOC prerelease version component (e.g. pre if %MONGOC_VERSION is 1.2.3-pre) */ -#define MONGOC_PRERELEASE_VERSION (pre) +#define MONGOC_PRERELEASE_VERSION () /** @@ -61,7 +62,7 @@ * * MONGOC version. */ -#define MONGOC_VERSION (1.23.2-pre) +#define MONGOC_VERSION (1.26.2) /** @@ -70,7 +71,7 @@ * MONGOC version, encoded as a string, useful for printing and * concatenation. */ -#define MONGOC_VERSION_S "1.23.2-pre" +#define MONGOC_VERSION_S "1.26.2" /** @@ -91,7 +92,7 @@ * @micro: required micro version * * Compile-time version checking. Evaluates to %TRUE if the version - * of MONGOC is greater than the required one. + * of MONGOC is greater than or equal to the required one. */ #define MONGOC_CHECK_VERSION(major,minor,micro) \ (MONGOC_MAJOR_VERSION > (major) || \ diff --git a/src/mongoc/mongoc-write-command-legacy-private.h b/src/mongoc/mongoc-write-command-legacy-private.h deleted file mode 100644 index e6fd4dbe..00000000 --- a/src/mongoc/mongoc-write-command-legacy-private.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2014-present MongoDB, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "mongoc-prelude.h" - - -#ifndef MONGOC_WRITE_COMMAND_LEGACY_PRIVATE_H -#define MONGOC_WRITE_COMMAND_LEGACY_PRIVATE_H - -#include -#include "mongoc-client-private.h" -#include "mongoc-write-command-private.h" - -BSON_BEGIN_DECLS - -void -_mongoc_write_command_insert_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error); -void -_mongoc_write_command_update_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error); -void -_mongoc_write_command_delete_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error); -BSON_END_DECLS - - -#endif /* MONGOC_WRITE_COMMAND_LEGACY_PRIVATE_H */ diff --git a/src/mongoc/mongoc-write-command-legacy.c b/src/mongoc/mongoc-write-command-legacy.c deleted file mode 100644 index 250fadff..00000000 --- a/src/mongoc/mongoc-write-command-legacy.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright 2014-present MongoDB, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "mongoc-write-command-legacy-private.h" -#include "mongoc-trace-private.h" -#include "mongoc-util-private.h" - -static void -_mongoc_monitor_legacy_write (mongoc_client_t *client, - mongoc_write_command_t *command, - const char *db, - const char *collection, - mongoc_server_stream_t *stream, - int64_t request_id) -{ - bson_t doc; - bson_t wc; - mongoc_apm_command_started_t event; - - ENTRY; - - if (!client->apm_callbacks.started) { - EXIT; - } - - bson_init (&doc); - _mongoc_write_command_init (&doc, command, collection); - BSON_APPEND_DOCUMENT_BEGIN (&doc, "writeConcern", &wc); - BSON_APPEND_INT32 (&wc, "w", 0); - bson_append_document_end (&doc, &wc); - - _append_array_from_command (command, &doc); - - mongoc_apm_command_started_init ( - &event, - &doc, - db, - _mongoc_command_type_to_name (command->type), - request_id, - command->operation_id, - &stream->sd->host, - stream->sd->id, - &stream->sd->service_id, - stream->sd->server_connection_id, - NULL, - client->apm_context); - - client->apm_callbacks.started (&event); - - mongoc_apm_command_started_cleanup (&event); - bson_destroy (&doc); -} - - -/* fire command-succeeded event as if we'd used a modern write command. - * note, cluster.request_id was incremented once for the write, again - * for the getLastError, so cluster.request_id is no longer valid; used the - * passed-in request_id instead. - */ -static void -_mongoc_monitor_legacy_write_succeeded (mongoc_client_t *client, - int64_t duration, - mongoc_write_command_t *command, - mongoc_server_stream_t *stream, - int64_t request_id) -{ - bson_t doc; - - mongoc_apm_command_succeeded_t event; - - ENTRY; - - if (!client->apm_callbacks.succeeded) { - EXIT; - } - - bson_init (&doc); - /* - * Unacknowledged writes must provide a CommandSucceededEvent with a { ok: 1 - * } reply. - * https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst#unacknowledged-acknowledged-writes - */ - bson_append_int32 (&doc, "ok", 2, 1); - bson_append_int32 (&doc, "n", 1, (int32_t) command->n_documents); - - mongoc_apm_command_succeeded_init ( - &event, - duration, - &doc, - _mongoc_command_type_to_name (command->type), - request_id, - command->operation_id, - &stream->sd->host, - stream->sd->id, - &stream->sd->service_id, - stream->sd->server_connection_id, - false, - client->apm_context); - - client->apm_callbacks.succeeded (&event); - - mongoc_apm_command_succeeded_cleanup (&event); - bson_destroy (&doc); - - EXIT; -} - - -void -_mongoc_write_command_delete_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error) -{ - int64_t started; - int32_t max_bson_obj_size; - const uint8_t *data; - mongoc_rpc_t rpc; - uint32_t request_id; - bson_iter_t q_iter; - uint32_t len; - int64_t limit = 0; - char *ns; - bool r; - bson_reader_t *reader; - const bson_t *bson; - bool eof; - - ENTRY; - - BSON_UNUSED (offset); - - BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (database); - BSON_ASSERT (server_stream); - BSON_ASSERT (collection); - - started = bson_get_monotonic_time (); - - max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); - - if (!command->n_documents) { - bson_set_error (error, - MONGOC_ERROR_COLLECTION, - MONGOC_ERROR_COLLECTION_DELETE_FAILED, - "Cannot do an empty delete."); - result->failed = true; - EXIT; - } - - ns = bson_strdup_printf ("%s.%s", database, collection); - - reader = - bson_reader_new_from_data (command->payload.data, command->payload.len); - while ((bson = bson_reader_read (reader, &eof))) { - /* the document is like { "q": { }, limit: <0 or 1> } */ - r = (bson_iter_init (&q_iter, bson) && bson_iter_find (&q_iter, "q") && - BSON_ITER_HOLDS_DOCUMENT (&q_iter)); - - BSON_ASSERT (r); - bson_iter_document (&q_iter, &len, &data); - BSON_ASSERT (data); - BSON_ASSERT (len >= 5); - if (len > max_bson_obj_size) { - _mongoc_write_command_too_large_error ( - error, 0, len, max_bson_obj_size); - result->failed = true; - bson_reader_destroy (reader); - bson_free (ns); - EXIT; - } - - request_id = ++client->cluster.request_id; - - rpc.header.msg_len = 0; - rpc.header.request_id = request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_DELETE; - rpc.delete_.zero = 0; - rpc.delete_.collection = ns; - - if (bson_iter_find (&q_iter, "limit") && - (BSON_ITER_HOLDS_INT (&q_iter))) { - limit = bson_iter_as_int64 (&q_iter); - } - - rpc.delete_.flags = - limit ? MONGOC_DELETE_SINGLE_REMOVE : MONGOC_DELETE_NONE; - rpc.delete_.selector = data; - - _mongoc_monitor_legacy_write ( - client, command, database, collection, server_stream, request_id); - - if (!mongoc_cluster_legacy_rpc_sendv_to_server ( - &client->cluster, &rpc, server_stream, error)) { - result->failed = true; - bson_free (ns); - bson_reader_destroy (reader); - EXIT; - } - - _mongoc_monitor_legacy_write_succeeded (client, - bson_get_monotonic_time () - - started, - command, - server_stream, - request_id); - - started = bson_get_monotonic_time (); - } - bson_reader_destroy (reader); - - bson_free (ns); - EXIT; -} - - -void -_mongoc_write_command_insert_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error) -{ - int64_t started; - mongoc_iovec_t *iov; - mongoc_rpc_t rpc; - uint32_t size = 0; - bool has_more; - char *ns; - uint32_t n_docs_in_batch; - uint32_t request_id = 0; - uint32_t idx = 0; - int32_t max_msg_size; - int32_t max_bson_obj_size; - bson_reader_t *reader; - const bson_t *bson; - bool eof; - int data_offset = 0; - - ENTRY; - - BSON_UNUSED (offset); - - BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (database); - BSON_ASSERT (server_stream); - BSON_ASSERT (collection); - BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_INSERT); - - started = bson_get_monotonic_time (); - - max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); - max_msg_size = mongoc_server_stream_max_msg_size (server_stream); - - if (!command->n_documents) { - bson_set_error (error, - MONGOC_ERROR_COLLECTION, - MONGOC_ERROR_COLLECTION_INSERT_FAILED, - "Cannot do an empty insert."); - result->failed = true; - EXIT; - } - - ns = bson_strdup_printf ("%s.%s", database, collection); - - iov = (mongoc_iovec_t *) bson_malloc ((sizeof *iov) * command->n_documents); - -again: - has_more = false; - n_docs_in_batch = 0; - size = (uint32_t) (sizeof (mongoc_rpc_header_t) + 4 + strlen (database) + 1 + - strlen (collection) + 1); - - reader = bson_reader_new_from_data (command->payload.data + data_offset, - command->payload.len - data_offset); - while ((bson = bson_reader_read (reader, &eof))) { - BSON_ASSERT (n_docs_in_batch <= idx); - BSON_ASSERT (idx <= command->n_documents); - - if (bson->len > max_bson_obj_size) { - /* document is too large */ - _mongoc_write_command_too_large_error ( - error, idx, bson->len, max_bson_obj_size); - - data_offset += bson->len; - - if (command->flags.ordered) { - /* send the batch so far (if any) and return the error */ - break; - } - } else if (size > (max_msg_size - bson->len)) { - /* batch is full, send it and then start the next batch */ - has_more = true; - break; - } else { - /* add document to batch and continue building the batch */ - iov[n_docs_in_batch].iov_base = (void *) bson_get_data (bson); - iov[n_docs_in_batch].iov_len = bson->len; - size += bson->len; - n_docs_in_batch++; - data_offset += bson->len; - } - - idx++; - } - bson_reader_destroy (reader); - - if (n_docs_in_batch) { - request_id = ++client->cluster.request_id; - - rpc.header.msg_len = 0; - rpc.header.request_id = request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_INSERT; - rpc.insert.flags = - ((command->flags.ordered) ? MONGOC_INSERT_NONE - : MONGOC_INSERT_CONTINUE_ON_ERROR); - rpc.insert.collection = ns; - rpc.insert.documents = iov; - rpc.insert.n_documents = n_docs_in_batch; - - _mongoc_monitor_legacy_write ( - client, command, database, collection, server_stream, request_id); - - if (!mongoc_cluster_legacy_rpc_sendv_to_server ( - &client->cluster, &rpc, server_stream, error)) { - result->failed = true; - GOTO (cleanup); - } - - _mongoc_monitor_legacy_write_succeeded (client, - bson_get_monotonic_time () - - started, - command, - server_stream, - request_id); - - started = bson_get_monotonic_time (); - } - -cleanup: - - if (has_more) { - GOTO (again); - } - - bson_free (ns); - bson_free (iov); - - EXIT; -} - - -void -_mongoc_write_command_update_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error) -{ - int64_t started; - int32_t max_bson_obj_size; - mongoc_rpc_t rpc; - uint32_t request_id = 0; - bson_iter_t subiter; - bson_t update, selector; - const uint8_t *data = NULL; - uint32_t len = 0; - bool val = false; - char *ns; - bool r; - bson_reader_t *reader; - const bson_t *bson; - bool eof; - - ENTRY; - - BSON_UNUSED (offset); - - BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (database); - BSON_ASSERT (server_stream); - BSON_ASSERT (collection); - - started = bson_get_monotonic_time (); - - max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); - - ns = bson_strdup_printf ("%s.%s", database, collection); - - reader = - bson_reader_new_from_data (command->payload.data, command->payload.len); - while ((bson = bson_reader_read (reader, &eof))) { - /* ensure the document has "q" and "u" document fields in that order */ - r = (bson_iter_init (&subiter, bson) && bson_iter_find (&subiter, "q") && - BSON_ITER_HOLDS_DOCUMENT (&subiter) && - bson_iter_find (&subiter, "u") && - BSON_ITER_HOLDS_DOCUMENT (&subiter)); - - BSON_ASSERT (r); - - request_id = ++client->cluster.request_id; - - rpc.header.msg_len = 0; - rpc.header.request_id = request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_UPDATE; - rpc.update.zero = 0; - rpc.update.collection = ns; - rpc.update.flags = MONGOC_UPDATE_NONE; - - BSON_ASSERT (bson_iter_init (&subiter, bson)); - while (bson_iter_next (&subiter)) { - if (strcmp (bson_iter_key (&subiter), "u") == 0) { - bson_iter_document (&subiter, &len, &data); - - BSON_ASSERT (data); - BSON_ASSERT (len >= 5); - - if (len > max_bson_obj_size) { - _mongoc_write_command_too_large_error ( - error, 0, len, max_bson_obj_size); - result->failed = true; - bson_reader_destroy (reader); - bson_free (ns); - EXIT; - } - - rpc.update.update = data; - BSON_ASSERT (bson_init_static (&update, data, len)); - } else if (strcmp (bson_iter_key (&subiter), "q") == 0) { - bson_iter_document (&subiter, &len, &data); - - BSON_ASSERT (data); - BSON_ASSERT (len >= 5); - - if (len > max_bson_obj_size) { - _mongoc_write_command_too_large_error ( - error, 0, len, max_bson_obj_size); - result->failed = true; - bson_reader_destroy (reader); - bson_free (ns); - EXIT; - } - - rpc.update.selector = data; - BSON_ASSERT (bson_init_static (&selector, data, len)); - } else if (strcmp (bson_iter_key (&subiter), "multi") == 0) { - val = bson_iter_bool (&subiter); - if (val) { - rpc.update.flags = - (mongoc_update_flags_t) (rpc.update.flags | - MONGOC_UPDATE_MULTI_UPDATE); - } - } else if (strcmp (bson_iter_key (&subiter), "upsert") == 0) { - val = bson_iter_bool (&subiter); - if (val) { - rpc.update.flags = - (mongoc_update_flags_t) (rpc.update.flags | - MONGOC_UPDATE_UPSERT); - } - } - } - - _mongoc_monitor_legacy_write ( - client, command, database, collection, server_stream, request_id); - - if (!mongoc_cluster_legacy_rpc_sendv_to_server ( - &client->cluster, &rpc, server_stream, error)) { - result->failed = true; - bson_reader_destroy (reader); - bson_free (ns); - EXIT; - } - - _mongoc_monitor_legacy_write_succeeded (client, - bson_get_monotonic_time () - - started, - command, - server_stream, - request_id); - - started = bson_get_monotonic_time (); - } - bson_reader_destroy (reader); - bson_free (ns); -} diff --git a/src/mongoc/mongoc-write-command-private.h b/src/mongoc/mongoc-write-command-private.h index 04917deb..bc1a2e3f 100644 --- a/src/mongoc/mongoc-write-command-private.h +++ b/src/mongoc/mongoc-write-command-private.h @@ -88,6 +88,9 @@ typedef struct { * primary, this contains the server id of the newly selected primary. Only * applies to OP_MSG. Is left at 0 if no retry occurs. */ uint32_t retry_server_id; + /* store the raw server response if an error occured */ + uint32_t n_errorReplies; + bson_t rawErrorReplies; } mongoc_write_result_t; @@ -99,11 +102,6 @@ typedef enum { } mongoc_write_err_type_t; -const char * -_mongoc_command_type_to_field_name (int command_type); -const char * -_mongoc_command_type_to_name (int command_type); - void _mongoc_write_command_destroy (mongoc_write_command_t *command); void @@ -164,11 +162,6 @@ _mongoc_write_command_delete_append (mongoc_write_command_t *command, const bson_t *opts); void -_mongoc_write_command_too_large_error (bson_error_t *error, - int32_t idx, - int32_t len, - int32_t max_bson_size); -void _mongoc_write_command_execute (mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, @@ -189,20 +182,6 @@ _mongoc_write_command_execute_idl (mongoc_write_command_t *command, mongoc_write_result_t *result); void _mongoc_write_result_init (mongoc_write_result_t *result); -void -_mongoc_write_result_append_upsert (mongoc_write_result_t *result, - int32_t idx, - const bson_value_t *value); -int32_t -_mongoc_write_result_merge_arrays (uint32_t offset, - mongoc_write_result_t *result, - bson_t *dest, - bson_iter_t *iter); -void -_mongoc_write_result_merge (mongoc_write_result_t *result, - mongoc_write_command_t *command, - const bson_t *reply, - uint32_t offset); #define MONGOC_WRITE_RESULT_COMPLETE(_result, ...) \ _mongoc_write_result_complete (_result, __VA_ARGS__, NULL) bool @@ -216,9 +195,6 @@ _mongoc_write_result_complete (mongoc_write_result_t *result, void _mongoc_write_result_destroy (mongoc_write_result_t *result); -void -_append_array_from_command (mongoc_write_command_t *command, bson_t *bson); - mongoc_write_err_type_t _mongoc_write_error_get_type (bson_t *reply); diff --git a/src/mongoc/mongoc-write-command.c b/src/mongoc/mongoc-write-command.c index a10a2f9e..83c71179 100644 --- a/src/mongoc/mongoc-write-command.c +++ b/src/mongoc/mongoc-write-command.c @@ -23,50 +23,16 @@ #include "mongoc-error-private.h" #include "mongoc-trace-private.h" #include "mongoc-write-command-private.h" -#include "mongoc-write-command-legacy-private.h" #include "mongoc-write-concern-private.h" #include "mongoc-util-private.h" #include "mongoc-opts-private.h" -/* - * TODO: - * - * - Remove error parameter to ops, favor result->error. - */ - -typedef void (*mongoc_write_op_t) (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error); - - /* indexed by MONGOC_WRITE_COMMAND_DELETE, INSERT, UPDATE */ static const char *gCommandNames[] = {"delete", "insert", "update"}; static const char *gCommandFields[] = {"deletes", "documents", "updates"}; static const uint32_t gCommandFieldLens[] = {7, 9, 7}; -static mongoc_write_op_t gLegacyWriteOps[3] = { - _mongoc_write_command_delete_legacy, - _mongoc_write_command_insert_legacy, - _mongoc_write_command_update_legacy}; - - -const char * -_mongoc_command_type_to_name (int command_type) -{ - return gCommandNames[command_type]; -} - -const char * -_mongoc_command_type_to_field_name (int command_type) -{ - return gCommandFields[command_type]; -} void _mongoc_write_command_insert_append (mongoc_write_command_t *command, @@ -168,7 +134,7 @@ _mongoc_write_command_delete_append (mongoc_write_command_t *command, EXIT; } -void +static void _mongoc_write_command_init_bulk (mongoc_write_command_t *command, int type, mongoc_bulk_write_flags_t flags, @@ -376,7 +342,7 @@ _mongoc_write_command_init (bson_t *doc, *------------------------------------------------------------------------- */ -void +static void _mongoc_write_command_too_large_error (bson_error_t *error, int32_t idx, int32_t len, @@ -393,7 +359,7 @@ _mongoc_write_command_too_large_error (bson_error_t *error, } -void +static void _empty_error (mongoc_write_command_t *command, bson_error_t *error) { static const uint32_t codes[] = {MONGOC_ERROR_COLLECTION_DELETE_FAILED, @@ -408,28 +374,214 @@ _empty_error (mongoc_write_command_t *command, bson_error_t *error) } -bool -_mongoc_write_command_will_overflow (uint32_t len_so_far, - uint32_t document_len, - uint32_t n_documents_written, - int32_t max_bson_size, - int32_t max_write_batch_size) +static int32_t +_mongoc_write_result_merge_arrays (uint32_t offset, + mongoc_write_result_t *result, /* IN */ + bson_t *dest, /* IN */ + bson_iter_t *iter) /* IN */ { - /* max BSON object size + 16k bytes. - * server guarantees there is enough room: SERVER-10643 - */ - int32_t max_cmd_size = max_bson_size + BSON_OBJECT_ALLOWANCE; + const bson_value_t *value; + bson_iter_t ar; + bson_iter_t citer; + int32_t idx; + int32_t count = 0; + int32_t aridx; + bson_t child; + const char *keyptr = NULL; + char key[12]; + int len; - BSON_ASSERT (max_bson_size); + ENTRY; - if (len_so_far + document_len > max_cmd_size) { - return true; - } else if (max_write_batch_size > 0 && - n_documents_written >= max_write_batch_size) { - return true; + BSON_ASSERT (result); + BSON_ASSERT (dest); + BSON_ASSERT (iter); + BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (iter)); + + aridx = bson_count_keys (dest); + + if (bson_iter_recurse (iter, &ar)) { + while (bson_iter_next (&ar)) { + if (BSON_ITER_HOLDS_DOCUMENT (&ar) && + bson_iter_recurse (&ar, &citer)) { + len = + (int) bson_uint32_to_string (aridx++, &keyptr, key, sizeof key); + bson_append_document_begin (dest, keyptr, len, &child); + while (bson_iter_next (&citer)) { + if (BSON_ITER_IS_KEY (&citer, "index")) { + idx = bson_iter_int32 (&citer) + offset; + BSON_APPEND_INT32 (&child, "index", idx); + } else { + value = bson_iter_value (&citer); + BSON_APPEND_VALUE (&child, bson_iter_key (&citer), value); + } + } + bson_append_document_end (dest, &child); + count++; + } + } } - return false; + RETURN (count); +} + + +static void +_mongoc_write_result_append_upsert (mongoc_write_result_t *result, + int32_t idx, + const bson_value_t *value) +{ + bson_t child; + const char *keyptr = NULL; + char key[12]; + int len; + + BSON_ASSERT (result); + BSON_ASSERT (value); + + len = (int) bson_uint32_to_string ( + result->upsert_append_count, &keyptr, key, sizeof key); + + bson_append_document_begin (&result->upserted, keyptr, len, &child); + BSON_APPEND_INT32 (&child, "index", idx); + BSON_APPEND_VALUE (&child, "_id", value); + bson_append_document_end (&result->upserted, &child); + + result->upsert_append_count++; +} + + +static void +_mongoc_write_result_merge (mongoc_write_result_t *result, /* IN */ + mongoc_write_command_t *command, /* IN */ + const bson_t *reply, /* IN */ + uint32_t offset) +{ + int32_t server_index = 0; + const bson_value_t *value; + bson_iter_t iter; + bson_iter_t citer; + bson_iter_t ar; + int32_t n_upserted = 0; + int32_t affected = 0; + + ENTRY; + + BSON_ASSERT (result); + BSON_ASSERT (reply); + + if (bson_iter_init_find (&iter, reply, "n") && + BSON_ITER_HOLDS_INT32 (&iter)) { + affected = bson_iter_int32 (&iter); + } + + if (bson_iter_init_find (&iter, reply, "writeErrors") && + BSON_ITER_HOLDS_ARRAY (&iter) && bson_iter_recurse (&iter, &citer) && + bson_iter_next (&citer)) { + result->failed = true; + } + + switch (command->type) { + case MONGOC_WRITE_COMMAND_INSERT: + result->nInserted += affected; + break; + case MONGOC_WRITE_COMMAND_DELETE: + result->nRemoved += affected; + break; + case MONGOC_WRITE_COMMAND_UPDATE: + + /* server returns each upserted _id with its index into this batch + * look for "upserted": [{"index": 4, "_id": ObjectId()}, ...] */ + if (bson_iter_init_find (&iter, reply, "upserted")) { + if (BSON_ITER_HOLDS_ARRAY (&iter) && + (bson_iter_recurse (&iter, &ar))) { + while (bson_iter_next (&ar)) { + if (BSON_ITER_HOLDS_DOCUMENT (&ar) && + bson_iter_recurse (&ar, &citer) && + bson_iter_find (&citer, "index") && + BSON_ITER_HOLDS_INT32 (&citer)) { + server_index = bson_iter_int32 (&citer); + + if (bson_iter_recurse (&ar, &citer) && + bson_iter_find (&citer, "_id")) { + value = bson_iter_value (&citer); + _mongoc_write_result_append_upsert ( + result, offset + server_index, value); + n_upserted++; + } + } + } + } + result->nUpserted += n_upserted; + /* + * XXX: The following addition to nMatched needs some checking. + * I'm highly skeptical of it. + */ + result->nMatched += BSON_MAX (0, (affected - n_upserted)); + } else { + result->nMatched += affected; + } + if (bson_iter_init_find (&iter, reply, "nModified") && + BSON_ITER_HOLDS_INT32 (&iter)) { + result->nModified += bson_iter_int32 (&iter); + } + break; + default: + BSON_ASSERT (false); + break; + } + + if (bson_iter_init_find (&iter, reply, "writeErrors") && + BSON_ITER_HOLDS_ARRAY (&iter)) { + _mongoc_write_result_merge_arrays ( + offset, result, &result->writeErrors, &iter); + } + + if (bson_iter_init_find (&iter, reply, "writeConcernError") && + BSON_ITER_HOLDS_DOCUMENT (&iter)) { + uint32_t len; + const uint8_t *data; + bson_t write_concern_error; + char str[16]; + const char *key; + + /* writeConcernError is a subdocument in the server response + * append it to the result->writeConcernErrors array */ + bson_iter_document (&iter, &len, &data); + BSON_ASSERT (bson_init_static (&write_concern_error, data, len)); + + bson_uint32_to_string ( + result->n_writeConcernErrors, &key, str, sizeof str); + + if (!bson_append_document ( + &result->writeConcernErrors, key, -1, &write_concern_error)) { + MONGOC_ERROR ("Error adding \"%s\" to writeConcernErrors.\n", key); + } + + result->n_writeConcernErrors++; + } + + /* If a server error ocurred, then append the raw response to the + * error_replies array. */ + if (!_mongoc_cmd_check_ok ( + reply, MONGOC_ERROR_API_VERSION_2, NULL /* error */)) { + char str[16]; + const char *key; + + bson_uint32_to_string (result->n_errorReplies, &key, str, sizeof str); + + if (!bson_append_document (&result->rawErrorReplies, key, -1, reply)) { + MONGOC_ERROR ("Error adding \"%s\" to errorReplies.\n", key); + } + + result->n_errorReplies++; + } + + /* inefficient if there are ever large numbers: for each label in each err, + * we linear-search result->errorLabels to see if it's included yet */ + _mongoc_bson_array_copy_labels_to (reply, &result->errorLabels); + + EXIT; } @@ -458,13 +610,12 @@ _mongoc_write_opmsg (mongoc_write_command_t *command, uint32_t payload_total_offset = 0; bool ship_it = false; int document_count = 0; - int32_t len; mongoc_server_stream_t *retry_server_stream = NULL; ENTRY; BSON_ASSERT (command); - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (database); BSON_ASSERT (server_stream); BSON_ASSERT (collection); @@ -482,8 +633,7 @@ _mongoc_write_opmsg (mongoc_write_command_t *command, mongoc_cmd_parts_init (&parts, client, database, MONGOC_QUERY_NONE, &cmd); parts.assembled.operation_id = command->operation_id; parts.is_write_command = true; - if (!mongoc_cmd_parts_set_write_concern ( - &parts, write_concern, server_stream->sd->max_wire_version, error)) { + if (!mongoc_cmd_parts_set_write_concern (&parts, write_concern, error)) { bson_destroy (&cmd); mongoc_cmd_parts_cleanup (&parts); EXIT; @@ -502,8 +652,7 @@ _mongoc_write_opmsg (mongoc_write_command_t *command, : MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES; BSON_ASSERT (bson_iter_init (&iter, &command->cmd_opts)); - if (!mongoc_cmd_parts_append_opts ( - &parts, &iter, server_stream->sd->max_wire_version, error)) { + if (!mongoc_cmd_parts_append_opts (&parts, &iter, error)) { bson_destroy (&cmd); mongoc_cmd_parts_cleanup (&parts); EXIT; @@ -530,22 +679,28 @@ _mongoc_write_opmsg (mongoc_write_command_t *command, 26 + parts.assembled.command->len + gCommandFieldLens[command->type] + 1; do { - memcpy (&len, + uint32_t ulen; + memcpy (&ulen, command->payload.data + payload_batch_size + payload_total_offset, 4); - len = BSON_UINT32_FROM_LE (len); + ulen = BSON_UINT32_FROM_LE (ulen); + + // Although messageLength is an int32, it should never be negative. + BSON_ASSERT (bson_in_range_unsigned (int32_t, ulen)); + const int32_t slen = (int32_t) ulen; - if (len > max_bson_obj_size + BSON_OBJECT_ALLOWANCE) { + if (slen > max_bson_obj_size + BSON_OBJECT_ALLOWANCE) { /* Quit if the document is too large */ _mongoc_write_command_too_large_error ( - error, index_offset, len, max_bson_obj_size); + error, index_offset, slen, max_bson_obj_size); result->failed = true; break; - } else if ((payload_batch_size + header) + len <= max_msg_size || + } else if (bson_cmp_less_equal_us (payload_batch_size + header + ulen, + max_msg_size) || document_count == 0) { /* The current batch is still under max batch size in bytes */ - payload_batch_size += len; + payload_batch_size += ulen; /* If this document filled the maximum document count */ if (++document_count == max_document_count) { @@ -581,13 +736,21 @@ _mongoc_write_opmsg (mongoc_write_command_t *command, &txn_number_iter, ++parts.assembled.session->server_session->txn_number); } + + // Store the original error and reply if needed. + struct { + bson_t reply; + bson_error_t error; + bool set; + } original_error = {.reply = {0}, .error = {0}, .set = false}; + retry: ret = mongoc_cluster_run_command_monitored ( &client->cluster, &parts.assembled, &reply, error); if (parts.is_retryable_write) { _mongoc_write_error_handle_labels ( - ret, error, &reply, server_stream->sd->max_wire_version); + ret, error, &reply, server_stream->sd); } /* Add this batch size so we skip these documents next time */ @@ -609,17 +772,38 @@ _mongoc_write_opmsg (mongoc_write_command_t *command, /* each write command may be retried at most once */ is_retryable = false; - if (retry_server_stream) { - mongoc_server_stream_cleanup (retry_server_stream); - } + { + mongoc_deprioritized_servers_t *const ds = + mongoc_deprioritized_servers_new (); + + if (retry_server_stream) { + mongoc_deprioritized_servers_add_if_sharded ( + ds, + retry_server_stream->topology_type, + retry_server_stream->sd); + mongoc_server_stream_cleanup (retry_server_stream); + } else { + mongoc_deprioritized_servers_add_if_sharded ( + ds, server_stream->topology_type, server_stream->sd); + } + + retry_server_stream = mongoc_cluster_stream_for_writes ( + &client->cluster, cs, ds, NULL, &ignored_error); - retry_server_stream = mongoc_cluster_stream_for_writes ( - &client->cluster, cs, NULL, &ignored_error); + mongoc_deprioritized_servers_destroy (ds); + } - if (retry_server_stream && - retry_server_stream->sd->max_wire_version >= - WIRE_VERSION_RETRY_WRITES) { + if (retry_server_stream) { parts.assembled.server_stream = retry_server_stream; + { + // Store the original error and reply before retry. + BSON_ASSERT (!original_error.set); // Retry only happens once. + original_error.set = true; + bson_copy_to (&reply, &original_error.reply); + if (error) { + original_error.error = *error; + } + } bson_destroy (&reply); GOTO (retry); } @@ -635,6 +819,17 @@ _mongoc_write_opmsg (mongoc_write_command_t *command, } } + // If a retry attempt fails with an error labeled NoWritesPerformed, + // drivers MUST return the original error. + if (original_error.set && + mongoc_error_has_label (&reply, "NoWritesPerformed")) { + if (error) { + *error = original_error.error; + } + bson_destroy (&reply); + bson_copy_to (&original_error.reply, &reply); + } + /* Result merge needs to know the absolute index for a document * so it can rewrite the error message which contains the relative * document index per batch @@ -643,6 +838,9 @@ _mongoc_write_opmsg (mongoc_write_command_t *command, index_offset += document_count; document_count = 0; bson_destroy (&reply); + if (original_error.set) { + bson_destroy (&original_error.reply); + } } /* While we have more documents to write */ } while (payload_total_offset < command->payload.len && !result->must_stop); @@ -670,239 +868,23 @@ _mongoc_write_opmsg (mongoc_write_command_t *command, void -_append_array_from_command (mongoc_write_command_t *command, bson_t *bson) +_mongoc_write_command_execute ( + mongoc_write_command_t *command, /* IN */ + mongoc_client_t *client, /* IN */ + mongoc_server_stream_t *server_stream, /* IN */ + const char *database, /* IN */ + const char *collection, /* IN */ + const mongoc_write_concern_t *write_concern, /* IN */ + uint32_t offset, /* IN */ + mongoc_client_session_t *cs, /* IN */ + mongoc_write_result_t *result) /* OUT */ { - bson_t ar; - bson_reader_t *reader; - char str[16]; - uint32_t i = 0; - const char *key; - bool eof; - const bson_t *current; - - - reader = - bson_reader_new_from_data (command->payload.data, command->payload.len); - - bson_append_array_begin (bson, - gCommandFields[command->type], - gCommandFieldLens[command->type], - &ar); - - while ((current = bson_reader_read (reader, &eof))) { - bson_uint32_to_string (i, &key, str, sizeof str); - BSON_APPEND_DOCUMENT (&ar, key, current); - i++; - } + mongoc_crud_opts_t crud = {0}; - bson_append_array_end (bson, &ar); - bson_reader_destroy (reader); -} - -/* Assemble the base @cmd with all of the command options. - * @parts is always initialized, even on error. - * This is called twice in _mongoc_write_opquery. - * Once with no payload documents, to determine the total size. And once with - * payload documents, to send the final command. */ -static bool -_assemble_cmd (bson_t *cmd, - mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const mongoc_write_concern_t *write_concern, - mongoc_cmd_parts_t *parts, - bson_error_t *error) -{ - bool ret; - bson_iter_t iter; - - mongoc_cmd_parts_init (parts, client, database, MONGOC_QUERY_NONE, cmd); - parts->is_write_command = true; - parts->assembled.operation_id = command->operation_id; - - ret = mongoc_cmd_parts_set_write_concern ( - parts, write_concern, server_stream->sd->max_wire_version, error); - if (ret) { - BSON_ASSERT (bson_iter_init (&iter, &command->cmd_opts)); - ret = mongoc_cmd_parts_append_opts ( - parts, &iter, server_stream->sd->max_wire_version, error); - } - if (ret) { - ret = mongoc_cmd_parts_assemble (parts, server_stream, error); - } - return ret; -} - -static void -_mongoc_write_opquery (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - const mongoc_write_concern_t *write_concern, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error) -{ - mongoc_cmd_parts_t parts; - const char *key; - uint32_t len = 0; - bson_t ar; - bson_t cmd; - char str[16]; - bool has_more; - bool ret = false; - uint32_t i; - int32_t max_bson_obj_size; - int32_t max_write_batch_size; - uint32_t overhead; - uint32_t key_len; - int data_offset = 0; - bson_reader_t *reader; - const bson_t *bson; - bool eof; - - ENTRY; + ENTRY; BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (database); - BSON_ASSERT (server_stream); - BSON_ASSERT (collection); - - bson_init (&cmd); - max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); - max_write_batch_size = - mongoc_server_stream_max_write_batch_size (server_stream); - -again: - has_more = false; - i = 0; - - _mongoc_write_command_init (&cmd, command, collection); - /* If any part of assembling failed, return with failure. */ - if (!_assemble_cmd (&cmd, - command, - client, - server_stream, - database, - write_concern, - &parts, - error)) { - result->failed = true; - bson_destroy (&cmd); - mongoc_cmd_parts_cleanup (&parts); - EXIT; - } - - /* Use the assembled command to compute the overhead, since it may be a new - * BSON document with options applied. If no options were applied, then - * parts.assembled.command points to cmd. The constant 2 is due to 1 byte to - * specify array type and 1 byte for field name's null terminator. */ - overhead = - parts.assembled.command->len + 2 + gCommandFieldLens[command->type]; - /* Toss out the assembled command, we'll assemble again after adding all of - * the payload documents. */ - mongoc_cmd_parts_cleanup (&parts); - - reader = bson_reader_new_from_data (command->payload.data + data_offset, - command->payload.len - data_offset); - - bson_append_array_begin (&cmd, - gCommandFields[command->type], - gCommandFieldLens[command->type], - &ar); - - while ((bson = bson_reader_read (reader, &eof))) { - key_len = (uint32_t) bson_uint32_to_string (i, &key, str, sizeof str); - len = bson->len; - /* 1 byte to specify document type, 1 byte for key's null terminator */ - if (_mongoc_write_command_will_overflow (overhead, - key_len + len + 2 + ar.len, - i, - max_bson_obj_size, - max_write_batch_size)) { - has_more = true; - break; - } - BSON_APPEND_DOCUMENT (&ar, key, bson); - data_offset += len; - i++; - } - - bson_append_array_end (&cmd, &ar); - - if (!i) { - _mongoc_write_command_too_large_error (error, i, len, max_bson_obj_size); - result->failed = true; - result->must_stop = true; - ret = false; - if (bson) { - data_offset += len; - } - } else { - bson_t reply; - - ret = _assemble_cmd (&cmd, - command, - client, - server_stream, - database, - write_concern, - &parts, - error); - if (ret) { - ret = mongoc_cluster_run_command_monitored ( - &client->cluster, &parts.assembled, &reply, error); - } else { - bson_init (&reply); - } - - if (!ret) { - result->failed = true; - if (bson_empty (&reply) || - !mongoc_cluster_stream_valid (&client->cluster, server_stream)) { - /* assembling failed, or a network error running the command */ - result->must_stop = true; - } - } - - _mongoc_write_result_merge (result, command, &reply, offset); - offset += i; - bson_destroy (&reply); - mongoc_cmd_parts_cleanup (&parts); - } - bson_reader_destroy (reader); - - if (has_more && (ret || !command->flags.ordered) && !result->must_stop) { - bson_reinit (&cmd); - GOTO (again); - } - - bson_destroy (&cmd); - EXIT; -} - - -void -_mongoc_write_command_execute ( - mongoc_write_command_t *command, /* IN */ - mongoc_client_t *client, /* IN */ - mongoc_server_stream_t *server_stream, /* IN */ - const char *database, /* IN */ - const char *collection, /* IN */ - const mongoc_write_concern_t *write_concern, /* IN */ - uint32_t offset, /* IN */ - mongoc_client_session_t *cs, /* IN */ - mongoc_write_result_t *result) /* OUT */ -{ - mongoc_crud_opts_t crud = {0}; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (server_stream); BSON_ASSERT (database); BSON_ASSERT (collection); @@ -948,7 +930,7 @@ _mongoc_write_command_execute_idl (mongoc_write_command_t *command, ENTRY; BSON_ASSERT (command); - BSON_ASSERT (client); + BSON_ASSERT_PARAM (client); BSON_ASSERT (server_stream); BSON_ASSERT (database); BSON_ASSERT (collection); @@ -963,15 +945,6 @@ _mongoc_write_command_execute_idl (mongoc_write_command_t *command, "Cannot set collation for unacknowledged writes"); EXIT; } - - if (server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) { - bson_set_error (&result->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - result->failed = true; - EXIT; - } } if (command->flags.has_array_filters) { @@ -983,22 +956,11 @@ _mongoc_write_command_execute_idl (mongoc_write_command_t *command, "Cannot use array filters with unacknowledged writes"); EXIT; } - - if (server_stream->sd->max_wire_version < WIRE_VERSION_ARRAY_FILTERS) { - bson_set_error (&result->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support array filters"); - result->failed = true; - EXIT; - } } if (command->flags.has_update_hint) { - if (server_stream->sd->max_wire_version < - WIRE_VERSION_HINT_SERVER_SIDE_ERROR || - (server_stream->sd->max_wire_version < WIRE_VERSION_UPDATE_HINT && - !mongoc_write_concern_is_acknowledged (crud->writeConcern))) { + if (server_stream->sd->max_wire_version < WIRE_VERSION_UPDATE_HINT && + !mongoc_write_concern_is_acknowledged (crud->writeConcern)) { bson_set_error ( &result->error, MONGOC_ERROR_COMMAND, @@ -1010,10 +972,8 @@ _mongoc_write_command_execute_idl (mongoc_write_command_t *command, } if (command->flags.has_delete_hint) { - if (server_stream->sd->max_wire_version < - WIRE_VERSION_HINT_SERVER_SIDE_ERROR || - (server_stream->sd->max_wire_version < WIRE_VERSION_DELETE_HINT && - !mongoc_write_concern_is_acknowledged (crud->writeConcern))) { + if (server_stream->sd->max_wire_version < WIRE_VERSION_DELETE_HINT && + !mongoc_write_concern_is_acknowledged (crud->writeConcern)) { bson_set_error ( &result->error, MONGOC_ERROR_COMMAND, @@ -1051,39 +1011,16 @@ _mongoc_write_command_execute_idl (mongoc_write_command_t *command, EXIT; } - if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) { - _mongoc_write_opmsg (command, - client, - server_stream, - database, - collection, - crud->writeConcern, - offset, - crud->client_session, - result, - &result->error); - } else { - if (mongoc_write_concern_is_acknowledged (crud->writeConcern)) { - _mongoc_write_opquery (command, - client, - server_stream, - database, - collection, - crud->writeConcern, - offset, - result, - &result->error); - } else { - gLegacyWriteOps[command->type](command, - client, - server_stream, - database, - collection, - offset, - result, - &result->error); - } - } + _mongoc_write_opmsg (command, + client, + server_stream, + database, + collection, + crud->writeConcern, + offset, + crud->client_session, + result, + &result->error); EXIT; } @@ -1116,6 +1053,7 @@ _mongoc_write_result_init (mongoc_write_result_t *result) /* IN */ bson_init (&result->writeConcernErrors); bson_init (&result->writeErrors); bson_init (&result->errorLabels); + bson_init (&result->rawErrorReplies); EXIT; } @@ -1132,201 +1070,7 @@ _mongoc_write_result_destroy (mongoc_write_result_t *result) bson_destroy (&result->writeConcernErrors); bson_destroy (&result->writeErrors); bson_destroy (&result->errorLabels); - - EXIT; -} - - -void -_mongoc_write_result_append_upsert (mongoc_write_result_t *result, - int32_t idx, - const bson_value_t *value) -{ - bson_t child; - const char *keyptr = NULL; - char key[12]; - int len; - - BSON_ASSERT (result); - BSON_ASSERT (value); - - len = (int) bson_uint32_to_string ( - result->upsert_append_count, &keyptr, key, sizeof key); - - bson_append_document_begin (&result->upserted, keyptr, len, &child); - BSON_APPEND_INT32 (&child, "index", idx); - BSON_APPEND_VALUE (&child, "_id", value); - bson_append_document_end (&result->upserted, &child); - - result->upsert_append_count++; -} - - -int32_t -_mongoc_write_result_merge_arrays (uint32_t offset, - mongoc_write_result_t *result, /* IN */ - bson_t *dest, /* IN */ - bson_iter_t *iter) /* IN */ -{ - const bson_value_t *value; - bson_iter_t ar; - bson_iter_t citer; - int32_t idx; - int32_t count = 0; - int32_t aridx; - bson_t child; - const char *keyptr = NULL; - char key[12]; - int len; - - ENTRY; - - BSON_ASSERT (result); - BSON_ASSERT (dest); - BSON_ASSERT (iter); - BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (iter)); - - aridx = bson_count_keys (dest); - - if (bson_iter_recurse (iter, &ar)) { - while (bson_iter_next (&ar)) { - if (BSON_ITER_HOLDS_DOCUMENT (&ar) && - bson_iter_recurse (&ar, &citer)) { - len = - (int) bson_uint32_to_string (aridx++, &keyptr, key, sizeof key); - bson_append_document_begin (dest, keyptr, len, &child); - while (bson_iter_next (&citer)) { - if (BSON_ITER_IS_KEY (&citer, "index")) { - idx = bson_iter_int32 (&citer) + offset; - BSON_APPEND_INT32 (&child, "index", idx); - } else { - value = bson_iter_value (&citer); - BSON_APPEND_VALUE (&child, bson_iter_key (&citer), value); - } - } - bson_append_document_end (dest, &child); - count++; - } - } - } - - RETURN (count); -} - - -void -_mongoc_write_result_merge (mongoc_write_result_t *result, /* IN */ - mongoc_write_command_t *command, /* IN */ - const bson_t *reply, /* IN */ - uint32_t offset) -{ - int32_t server_index = 0; - const bson_value_t *value; - bson_iter_t iter; - bson_iter_t citer; - bson_iter_t ar; - int32_t n_upserted = 0; - int32_t affected = 0; - - ENTRY; - - BSON_ASSERT (result); - BSON_ASSERT (reply); - - if (bson_iter_init_find (&iter, reply, "n") && - BSON_ITER_HOLDS_INT32 (&iter)) { - affected = bson_iter_int32 (&iter); - } - - if (bson_iter_init_find (&iter, reply, "writeErrors") && - BSON_ITER_HOLDS_ARRAY (&iter) && bson_iter_recurse (&iter, &citer) && - bson_iter_next (&citer)) { - result->failed = true; - } - - switch (command->type) { - case MONGOC_WRITE_COMMAND_INSERT: - result->nInserted += affected; - break; - case MONGOC_WRITE_COMMAND_DELETE: - result->nRemoved += affected; - break; - case MONGOC_WRITE_COMMAND_UPDATE: - - /* server returns each upserted _id with its index into this batch - * look for "upserted": [{"index": 4, "_id": ObjectId()}, ...] */ - if (bson_iter_init_find (&iter, reply, "upserted")) { - if (BSON_ITER_HOLDS_ARRAY (&iter) && - (bson_iter_recurse (&iter, &ar))) { - while (bson_iter_next (&ar)) { - if (BSON_ITER_HOLDS_DOCUMENT (&ar) && - bson_iter_recurse (&ar, &citer) && - bson_iter_find (&citer, "index") && - BSON_ITER_HOLDS_INT32 (&citer)) { - server_index = bson_iter_int32 (&citer); - - if (bson_iter_recurse (&ar, &citer) && - bson_iter_find (&citer, "_id")) { - value = bson_iter_value (&citer); - _mongoc_write_result_append_upsert ( - result, offset + server_index, value); - n_upserted++; - } - } - } - } - result->nUpserted += n_upserted; - /* - * XXX: The following addition to nMatched needs some checking. - * I'm highly skeptical of it. - */ - result->nMatched += BSON_MAX (0, (affected - n_upserted)); - } else { - result->nMatched += affected; - } - if (bson_iter_init_find (&iter, reply, "nModified") && - BSON_ITER_HOLDS_INT32 (&iter)) { - result->nModified += bson_iter_int32 (&iter); - } - break; - default: - BSON_ASSERT (false); - break; - } - - if (bson_iter_init_find (&iter, reply, "writeErrors") && - BSON_ITER_HOLDS_ARRAY (&iter)) { - _mongoc_write_result_merge_arrays ( - offset, result, &result->writeErrors, &iter); - } - - if (bson_iter_init_find (&iter, reply, "writeConcernError") && - BSON_ITER_HOLDS_DOCUMENT (&iter)) { - uint32_t len; - const uint8_t *data; - bson_t write_concern_error; - char str[16]; - const char *key; - - /* writeConcernError is a subdocument in the server response - * append it to the result->writeConcernErrors array */ - bson_iter_document (&iter, &len, &data); - BSON_ASSERT (bson_init_static (&write_concern_error, data, len)); - - bson_uint32_to_string ( - result->n_writeConcernErrors, &key, str, sizeof str); - - if (!bson_append_document ( - &result->writeConcernErrors, key, -1, &write_concern_error)) { - MONGOC_ERROR ("Error adding \"%s\" to writeConcernErrors.\n", key); - } - - result->n_writeConcernErrors++; - } - - /* inefficient if there are ever large numbers: for each label in each err, - * we linear-search result->errorLabels to see if it's included yet */ - _mongoc_bson_array_copy_labels_to (reply, &result->errorLabels); + bson_destroy (&result->rawErrorReplies); EXIT; } @@ -1434,6 +1178,7 @@ _mongoc_write_result_complete ( /* produce either old fields like nModified from the deprecated Bulk API Spec * or new fields like modifiedCount from the CRUD Spec, which we partly obey */ + if (bson && mongoc_write_concern_is_acknowledged (wc)) { n_args = 0; va_start (args, error); @@ -1498,6 +1243,12 @@ _mongoc_write_result_complete ( } } + /* If there is a raw error response then we know a server error has occurred. + * We should add the raw result to the reply. */ + if (bson && !bson_empty (&result->rawErrorReplies)) { + BSON_APPEND_ARRAY (bson, "errorReplies", &result->rawErrorReplies); + } + /* set bson_error_t from first write error or write concern error */ _set_error_from_response ( &result->writeErrors, domain, "write", &result->error); diff --git a/src/mongoc/mongoc.h b/src/mongoc/mongoc.h index 24d69e47..a43304ce 100644 --- a/src/mongoc/mongoc.h +++ b/src/mongoc/mongoc.h @@ -47,6 +47,7 @@ #include "mongoc-handshake.h" #include "mongoc-opcode.h" #include "mongoc-log.h" +#include "mongoc-sleep.h" #include "mongoc-socket.h" #include "mongoc-client-session.h" #include "mongoc-stream.h" diff --git a/src/mongoc/op-compressed.def b/src/mongoc/op-compressed.def deleted file mode 100644 index 59f5e377..00000000 --- a/src/mongoc/op-compressed.def +++ /dev/null @@ -1,11 +0,0 @@ -RPC( - compressed, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - INT32_FIELD(original_opcode) - INT32_FIELD(uncompressed_size) - UINT8_FIELD(compressor_id) - RAW_BUFFER_FIELD(compressed_message) -) diff --git a/src/mongoc/op-delete.def b/src/mongoc/op-delete.def deleted file mode 100644 index ee69d467..00000000 --- a/src/mongoc/op-delete.def +++ /dev/null @@ -1,11 +0,0 @@ -RPC( - delete, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - INT32_FIELD(zero) - CSTRING_FIELD(collection) - ENUM_FIELD(flags) - BSON_FIELD(selector) -) diff --git a/src/mongoc/op-get-more.def b/src/mongoc/op-get-more.def deleted file mode 100644 index 3d7da748..00000000 --- a/src/mongoc/op-get-more.def +++ /dev/null @@ -1,11 +0,0 @@ -RPC( - get_more, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - INT32_FIELD(zero) - CSTRING_FIELD(collection) - INT32_FIELD(n_return) - INT64_FIELD(cursor_id) -) diff --git a/src/mongoc/op-header.def b/src/mongoc/op-header.def deleted file mode 100644 index 093bd4b3..00000000 --- a/src/mongoc/op-header.def +++ /dev/null @@ -1,7 +0,0 @@ -RPC( - header, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) -) diff --git a/src/mongoc/op-insert.def b/src/mongoc/op-insert.def deleted file mode 100644 index 290ddce4..00000000 --- a/src/mongoc/op-insert.def +++ /dev/null @@ -1,10 +0,0 @@ -RPC( - insert, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - ENUM_FIELD(flags) - CSTRING_FIELD(collection) - IOVEC_ARRAY_FIELD(documents) -) diff --git a/src/mongoc/op-kill-cursors.def b/src/mongoc/op-kill-cursors.def deleted file mode 100644 index 1c3758e2..00000000 --- a/src/mongoc/op-kill-cursors.def +++ /dev/null @@ -1,9 +0,0 @@ -RPC( - kill_cursors, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - INT32_FIELD(zero) - INT64_ARRAY_FIELD(n_cursors, cursors) -) diff --git a/src/mongoc/op-msg.def b/src/mongoc/op-msg.def deleted file mode 100644 index 2550bf6d..00000000 --- a/src/mongoc/op-msg.def +++ /dev/null @@ -1,9 +0,0 @@ -RPC( - msg, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - ENUM_FIELD(flags) - SECTION_ARRAY_FIELD(sections) -) diff --git a/src/mongoc/op-query.def b/src/mongoc/op-query.def deleted file mode 100644 index 7a014743..00000000 --- a/src/mongoc/op-query.def +++ /dev/null @@ -1,13 +0,0 @@ -RPC( - query, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - ENUM_FIELD(flags) - CSTRING_FIELD(collection) - INT32_FIELD(skip) - INT32_FIELD(n_return) - BSON_FIELD(query) - BSON_OPTIONAL(fields, BSON_FIELD(fields)) -) diff --git a/src/mongoc/op-reply-header.def b/src/mongoc/op-reply-header.def deleted file mode 100644 index f272362f..00000000 --- a/src/mongoc/op-reply-header.def +++ /dev/null @@ -1,11 +0,0 @@ -RPC( - reply_header, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - ENUM_FIELD(flags) - INT64_FIELD(cursor_id) - INT32_FIELD(start_from) - INT32_FIELD(n_returned) -) diff --git a/src/mongoc/op-reply.def b/src/mongoc/op-reply.def deleted file mode 100644 index c4cf8f0c..00000000 --- a/src/mongoc/op-reply.def +++ /dev/null @@ -1,12 +0,0 @@ -RPC( - reply, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - ENUM_FIELD(flags) - INT64_FIELD(cursor_id) - INT32_FIELD(start_from) - INT32_FIELD(n_returned) - BSON_ARRAY_FIELD(documents) -) diff --git a/src/mongoc/op-update.def b/src/mongoc/op-update.def deleted file mode 100644 index 2b1d2d79..00000000 --- a/src/mongoc/op-update.def +++ /dev/null @@ -1,12 +0,0 @@ -RPC( - update, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - INT32_FIELD(zero) - CSTRING_FIELD(collection) - ENUM_FIELD(flags) - BSON_FIELD(selector) - BSON_FIELD(update) -) diff --git a/src/mongoc/service-gcp.c b/src/mongoc/service-gcp.c new file mode 100644 index 00000000..d709610e --- /dev/null +++ b/src/mongoc/service-gcp.c @@ -0,0 +1,181 @@ +/** + * Copyright 2022 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "./service-gcp.h" + +#include "mongoc-util-private.h" + +#define HOST "metadata.google.internal" + +static const char *const DEFAULT_METADATA_PATH = + "/computeMetadata/v1/instance/service-accounts/default/token"; + +void +gcp_request_init (gcp_request *req, + const char *const opt_host, + int opt_port, + const char *const opt_extra_headers) +{ + BSON_ASSERT_PARAM (req); + _mongoc_http_request_init (&req->req); + + // The HTTP host of the Google metadata server + req->req.host = req->_owned_host = bson_strdup (opt_host ? opt_host : HOST); + + if (opt_port) { + req->req.port = opt_port; + } else { + req->req.port = 80; + } + + // Empty body + req->req.body = ""; + // We GET + req->req.method = "GET"; + + req->req.extra_headers = req->_owned_headers = + bson_strdup_printf ("Metadata-Flavor: Google\r\n%s", + opt_extra_headers ? opt_extra_headers : ""); + + req->req.path = req->_owned_path = bson_strdup (DEFAULT_METADATA_PATH); +} + +void +gcp_request_destroy (gcp_request *req) +{ + BSON_ASSERT_PARAM (req); + bson_free (req->_owned_headers); + bson_free (req->_owned_host); + bson_free (req->_owned_path); + *req = (gcp_request){ + .req = {0}, + ._owned_path = NULL, + ._owned_host = NULL, + ._owned_headers = NULL, + }; +} + +void +gcp_access_token_destroy (gcp_service_account_token *token) +{ + bson_free (token->access_token); + bson_free (token->token_type); + token->access_token = NULL; + token->token_type = NULL; +} + +bool +gcp_access_token_try_parse_from_json (gcp_service_account_token *out, + const char *json, + int len, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (out); + BSON_ASSERT_PARAM (json); + bool okay = false; + + // Zero the output + *out = (gcp_service_account_token){0}; + + // Parse the JSON data + bson_t bson; + if (!bson_init_from_json (&bson, json, len, error)) { + return false; + } + + bson_iter_t iter; + // access_token + bool found = bson_iter_init_find (&iter, &bson, "access_token"); + const char *const access_token = + !found ? NULL : bson_iter_utf8 (&iter, NULL); + // token_type + found = bson_iter_init_find (&iter, &bson, "token_type"); + const char *const token_type = !found ? NULL : bson_iter_utf8 (&iter, NULL); + + if (!(access_token && token_type)) { + bson_set_error (error, + MONGOC_ERROR_GCP, + MONGOC_ERROR_KMS_SERVER_BAD_JSON, + "One or more required JSON properties are " + "missing/invalid: data: %.*s", + len, + json); + goto done; + } + + *out = (gcp_service_account_token){ + .access_token = bson_strdup (access_token), + .token_type = bson_strdup (token_type), + }; + okay = true; + +done: + bson_destroy (&bson); + return okay; +} + +bool +gcp_access_token_from_gcp_server (gcp_service_account_token *out, + const char *opt_host, + int opt_port, + const char *opt_extra_headers, + bson_error_t *error) +{ + BSON_ASSERT_PARAM (out); + bool okay = false; + + // Clear the output + *out = (gcp_service_account_token){0}; + + mongoc_http_response_t resp; + _mongoc_http_response_init (&resp); + + gcp_request req = { + .req = {0}, + ._owned_path = NULL, + ._owned_host = NULL, + ._owned_headers = NULL, + }; + gcp_request_init (&req, opt_host, opt_port, opt_extra_headers); + + if (!_mongoc_http_send (&req.req, 3 * 1000, false, NULL, &resp, error)) { + goto fail; + } + + // Only accept an HTTP 200 as success + if (resp.status != 200) { + bson_set_error (error, + MONGOC_ERROR_GCP, + MONGOC_ERROR_KMS_SERVER_HTTP, + "Error from the GCP metadata server while looking for " + "access token: %.*s", + resp.body_len, + resp.body); + goto fail; + } + + if (!gcp_access_token_try_parse_from_json ( + out, resp.body, resp.body_len, error)) { + goto fail; + } + + okay = true; + +fail: + gcp_request_destroy (&req); + _mongoc_http_response_cleanup (&resp); + return okay; +} diff --git a/src/mongoc/service-gcp.h b/src/mongoc/service-gcp.h new file mode 100644 index 00000000..fdf19de9 --- /dev/null +++ b/src/mongoc/service-gcp.h @@ -0,0 +1,126 @@ +/** + * Copyright 2022 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SERVICE_GCP_H_INCLUDED +#define SERVICE_GCP_H_INCLUDED + +#include "mongoc-prelude.h" + +#include + +#include + +/** + * @brief A GCP access token obtained from the GCP metadata server + */ +typedef struct gcp_service_account_token { + /// The access token string + char *access_token; + // The HTTP type of the token + char *token_type; +} gcp_service_account_token; + +/** + * @brief A GCP request + */ +typedef struct gcp_request { + /// The underlying HTTP request object to be sent + mongoc_http_request_t req; + // optional parameters (used in testing) to override defaults + char *_owned_path; + char *_owned_host; + char *_owned_headers; +} gcp_request; + +/** + * @brief Initialize a new GCP HTTP request + * + * @param out The object to initialize + * @param opt_host (Optional) the IP host of the metadata server (default is + * metadata.google.internal) + * @param opt_port (Optional) The port of the HTTP server (default is 80) + * @param opt_extra_headers (Optional) Set extra HTTP headers for the request + * + * @note the request must later be destroyed with gcp_request_destroy + */ +void +gcp_request_init (gcp_request *req, + const char *const opt_host, + int opt_port, + const char *const opt_extra_headers); + + +/** + * @brief Destroy an GCP request created with gcp_request_init() + * + * @param req + */ +void +gcp_request_destroy (gcp_request *req); + +/** + * @brief Destroy and zero-fill GCP service account token + * + * @param token The service account token to destory + */ +void +gcp_access_token_destroy (gcp_service_account_token *token); + + +/** + * @brief Try to parse a GCP access token from the metadata server JSON response + * + * @param out The token to initialize. Should be uninitialized. Must later be + * destroyed by the caller. + * @param json The JSON string body + * @param len The length of 'body' + * @param error An output parameter for errors + * @retval true If 'out' was successfully initialized to a token. + * @retval false Otherwise + * + * @note The 'out' token must later be given to gcp_access_token_destroy + */ +bool +gcp_access_token_try_parse_from_json (gcp_service_account_token *out, + const char *json, + int len, + bson_error_t *error); + +/** + * @brief Attempt to obtain a new GCP service account token from a GCP metadata + * server. + * + * @param out The output parameter for the obtained token. Must later be + * destroyed + * @param opt_host (Optional) Override the IP host of the GCP server (used + * in testing) + * @param opt_port (Optional) The port of the HTTP server (default is 80) + * (used in testing) + * @param opt_extra_headers (Optional) Set extra HTTP headers for the request + * (used in testing) + * @param error Output parameter for errors + * @retval true Upon success + * @retval false Otherwise. Sets an error via `error` + * + */ +bool +gcp_access_token_from_gcp_server (gcp_service_account_token *out, + const char *opt_host, + int opt_port, + const char *opt_extra_headers, + bson_error_t *error); + +#endif /* SERVICE_GCP_H */ diff --git a/src/osx/Makevars b/src/osx/Makevars index 190e33d6..9ebd68f7 100644 --- a/src/osx/Makevars +++ b/src/osx/Makevars @@ -1,9 +1,10 @@ # Special config for native MacOS SSL (Secure Transport) instead of OpenSSL -PKG_CPPFLAGS=-I. -Icommon -Ikms \ +PKG_CPPFLAGS=-I. -Icommon -Ikms -Iutf8proc \ -DBSON_COMPILATION -DBSON_EXTRA_ALIGN \ -DMONGOC_COMPILATION -DMONGOC_HAVE_SASL_CLIENT_DONE \ -DMONGOC_ENABLE_SSL_SECURE_TRANSPORT -DMONGOC_ENABLE_CRYPTO_COMMON_CRYPTO \ - -DKMS_MESSAGE_ENABLE_CRYPTO -DKMS_MESSAGE_ENABLE_CRYPTO_COMMON_CRYPTO + -DKMS_MESSAGE_ENABLE_CRYPTO -DKMS_MESSAGE_ENABLE_CRYPTO_COMMON_CRYPTO \ + -D_DARWIN_C_SOURCE LIBBSON=bson/bcon.o bson/bson-clock.o bson/bson-context.o common/common-md5.o \ bson/bson-error.o bson/bson-iso8601.o bson/bson-iter.o bson/bson-json.o \ @@ -32,8 +33,8 @@ LIBMONGOC=mongoc/mongoc-array.o common/common-b64.o mongoc/mongoc-buffer.o \ mongoc/mongoc-stream-tls-secure-transport.o \ mongoc/mongoc-cluster-sasl.o mongoc/mongoc-cmd.o \ mongoc/mongoc-change-stream.o mongoc/mongoc-client-session.o mongoc/mongoc-cluster-cyrus.o \ - mongoc/mongoc-compression.o mongoc/mongoc-cyrus.o mongoc/mongoc-write-command-legacy.o \ - mongoc/mongoc-stream-file.o \ + mongoc/mongoc-compression.o mongoc/mongoc-cyrus.o \ + mongoc/mongoc-stream-file.o mongoc/mcd-rpc.o mongoc/mongoc-deprioritized-servers.o \ mongoc/mongoc-opts.o mongoc/mongoc-opts-helpers.o \ mongoc/mongoc-cursor-cmd.o mongoc/mongoc-cursor-cmd-deprecated.o \ mongoc/mongoc-cursor-find.o mongoc/mongoc-cursor-find-cmd.o mongoc/mongoc-cursor-find-opquery.o \ @@ -41,7 +42,8 @@ LIBMONGOC=mongoc/mongoc-array.o common/common-b64.o mongoc/mongoc-buffer.o \ mongoc/mongoc-client-side-encryption.o mongoc/mongoc-cursor-change-stream.o mongoc/mongoc-change-stream.o \ mongoc/mongoc-cluster-aws.o mongoc/mongoc-generation-map.o mongoc/mongoc-timeout.o \ mongoc/mongoc-server-monitor.o mongoc/mongoc-topology-background-monitoring.o common/common-thread.o \ - mongoc/mongoc-optional.o mongoc/mongoc-server-api.o mongoc/mongoc-http.o mongoc/mongoc-shared.o mongoc/mongoc-ts-pool.o + mongoc/mongoc-optional.o mongoc/mongoc-server-api.o mongoc/mongoc-http.o mongoc/mongoc-shared.o mongoc/mongoc-ts-pool.o \ + utf8proc/utf8proc.o LIBKMS=kms/hexlify.o kms/kms_crypto_apple.o kms/kms_kv_list.o kms/kms_request.o \ kms/kms_response.o kms/kms_b64.o kms/kms_crypto_libcrypto.o kms/kms_decrypt_request.o kms/kms_message.o \ diff --git a/src/utf8proc/LICENSE.md b/src/utf8proc/LICENSE.md new file mode 100644 index 00000000..f18b1f3a --- /dev/null +++ b/src/utf8proc/LICENSE.md @@ -0,0 +1,93 @@ +## utf8proc license ## + +**utf8proc** is a software package originally developed +by Jan Behrens and the rest of the Public Software Group, who +deserve nearly all of the credit for this library, that is now maintained by the Julia-language developers. Like the original utf8proc, +whose copyright and license statements are reproduced below, all new +work on the utf8proc library is licensed under the [MIT "expat" +license](http://opensource.org/licenses/MIT): + +*Copyright © 2014-2021 by Steven G. Johnson, Jiahao Chen, Tony Kelman, Jonas Fonseca, and other contributors listed in the git history.* + +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. + +## Original utf8proc license ## + +*Copyright (c) 2009, 2013 Public Software Group e. V., Berlin, Germany* + +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. + +## Unicode data license ## + +This software contains data (`utf8proc_data.c`) derived from processing +the Unicode data files. The following license applies to that data: + +**COPYRIGHT AND PERMISSION NOTICE** + +*Copyright (c) 1991-2007 Unicode, Inc. All rights reserved. Distributed +under the Terms of Use in http://www.unicode.org/copyright.html.* + +Permission is hereby granted, free of charge, to any person obtaining a +copy of the Unicode data files and any associated documentation (the "Data +Files") or Unicode software and any associated documentation (the +"Software") to deal in the Data Files or Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, and/or sell copies of the Data Files or Software, and +to permit persons to whom the Data Files or Software are furnished to do +so, provided that (a) the above copyright notice(s) and this permission +notice appear with all copies of the Data Files or Software, (b) both the +above copyright notice(s) and this permission notice appear in associated +documentation, and (c) there is clear notice in each modified Data File or +in the Software as well as in the documentation associated with the Data +File(s) or Software that the data or software has been modified. + +THE DATA FILES AND SOFTWARE ARE 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 OF +THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS +INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR +CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THE DATA FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. + +Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be +registered in some jurisdictions. All other trademarks and registered +trademarks mentioned herein are the property of their respective owners. diff --git a/src/utf8proc/utf8proc.c b/src/utf8proc/utf8proc.c new file mode 100644 index 00000000..000afb17 --- /dev/null +++ b/src/utf8proc/utf8proc.c @@ -0,0 +1,792 @@ +/* -*- mode: c; c-basic-offset: 2; tab-width: 2; indent-tabs-mode: nil -*- */ +/* + * Copyright (c) 2014-2021 Steven G. Johnson, Jiahao Chen, Peter Colberg, Tony Kelman, Scott P. Jones, and other contributors. + * Copyright (c) 2009 Public Software Group e. V., Berlin, Germany + * + * 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. + */ + +/* + * This library contains derived data from a modified version of the + * Unicode data files. + * + * The original data files are available at + * https://www.unicode.org/Public/UNIDATA/ + * + * Please notice the copyright statement in the file "utf8proc_data.c". + */ + + +/* + * File name: utf8proc.c + * + * Description: + * Implementation of libutf8proc. + */ + + +#include "utf8proc.h" + +#ifndef SSIZE_MAX +#define SSIZE_MAX ((size_t)SIZE_MAX/2) +#endif +#ifndef UINT16_MAX +# define UINT16_MAX 65535U +#endif + +#include "utf8proc_data.c" + + +UTF8PROC_DLLEXPORT const utf8proc_int8_t utf8proc_utf8class[256] = { + 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, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 }; + +#define UTF8PROC_HANGUL_SBASE 0xAC00 +#define UTF8PROC_HANGUL_LBASE 0x1100 +#define UTF8PROC_HANGUL_VBASE 0x1161 +#define UTF8PROC_HANGUL_TBASE 0x11A7 +#define UTF8PROC_HANGUL_LCOUNT 19 +#define UTF8PROC_HANGUL_VCOUNT 21 +#define UTF8PROC_HANGUL_TCOUNT 28 +#define UTF8PROC_HANGUL_NCOUNT 588 +#define UTF8PROC_HANGUL_SCOUNT 11172 +/* END is exclusive */ +#define UTF8PROC_HANGUL_L_START 0x1100 +#define UTF8PROC_HANGUL_L_END 0x115A +#define UTF8PROC_HANGUL_L_FILLER 0x115F +#define UTF8PROC_HANGUL_V_START 0x1160 +#define UTF8PROC_HANGUL_V_END 0x11A3 +#define UTF8PROC_HANGUL_T_START 0x11A8 +#define UTF8PROC_HANGUL_T_END 0x11FA +#define UTF8PROC_HANGUL_S_START 0xAC00 +#define UTF8PROC_HANGUL_S_END 0xD7A4 + +/* Should follow semantic-versioning rules (semver.org) based on API + compatibility. (Note that the shared-library version number will + be different, being based on ABI compatibility.): */ +#define STRINGIZEx(x) #x +#define STRINGIZE(x) STRINGIZEx(x) +UTF8PROC_DLLEXPORT const char *utf8proc_version(void) { + return STRINGIZE(UTF8PROC_VERSION_MAJOR) "." STRINGIZE(UTF8PROC_VERSION_MINOR) "." STRINGIZE(UTF8PROC_VERSION_PATCH) ""; +} + +UTF8PROC_DLLEXPORT const char *utf8proc_unicode_version(void) { + return "15.0.0"; +} + +UTF8PROC_DLLEXPORT const char *utf8proc_errmsg(utf8proc_ssize_t errcode) { + switch (errcode) { + case UTF8PROC_ERROR_NOMEM: + return "Memory for processing UTF-8 data could not be allocated."; + case UTF8PROC_ERROR_OVERFLOW: + return "UTF-8 string is too long to be processed."; + case UTF8PROC_ERROR_INVALIDUTF8: + return "Invalid UTF-8 string"; + case UTF8PROC_ERROR_NOTASSIGNED: + return "Unassigned Unicode code point found in UTF-8 string."; + case UTF8PROC_ERROR_INVALIDOPTS: + return "Invalid options for UTF-8 processing chosen."; + default: + return "An unknown error occurred while processing UTF-8 data."; + } +} + +#define utf_cont(ch) (((ch) & 0xc0) == 0x80) +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_iterate( + const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_int32_t *dst +) { + utf8proc_int32_t uc; + const utf8proc_uint8_t *end; + + *dst = -1; + if (!strlen) return 0; + end = str + ((strlen < 0) ? 4 : strlen); + uc = *str++; + if (uc < 0x80) { + *dst = uc; + return 1; + } + // Must be between 0xc2 and 0xf4 inclusive to be valid + if ((utf8proc_uint32_t)(uc - 0xc2) > (0xf4-0xc2)) return UTF8PROC_ERROR_INVALIDUTF8; + if (uc < 0xe0) { // 2-byte sequence + // Must have valid continuation character + if (str >= end || !utf_cont(*str)) return UTF8PROC_ERROR_INVALIDUTF8; + *dst = ((uc & 0x1f)<<6) | (*str & 0x3f); + return 2; + } + if (uc < 0xf0) { // 3-byte sequence + if ((str + 1 >= end) || !utf_cont(*str) || !utf_cont(str[1])) + return UTF8PROC_ERROR_INVALIDUTF8; + // Check for surrogate chars + if (uc == 0xed && *str > 0x9f) + return UTF8PROC_ERROR_INVALIDUTF8; + uc = ((uc & 0xf)<<12) | ((*str & 0x3f)<<6) | (str[1] & 0x3f); + if (uc < 0x800) + return UTF8PROC_ERROR_INVALIDUTF8; + *dst = uc; + return 3; + } + // 4-byte sequence + // Must have 3 valid continuation characters + if ((str + 2 >= end) || !utf_cont(*str) || !utf_cont(str[1]) || !utf_cont(str[2])) + return UTF8PROC_ERROR_INVALIDUTF8; + // Make sure in correct range (0x10000 - 0x10ffff) + if (uc == 0xf0) { + if (*str < 0x90) return UTF8PROC_ERROR_INVALIDUTF8; + } else if (uc == 0xf4) { + if (*str > 0x8f) return UTF8PROC_ERROR_INVALIDUTF8; + } + *dst = ((uc & 7)<<18) | ((*str & 0x3f)<<12) | ((str[1] & 0x3f)<<6) | (str[2] & 0x3f); + return 4; +} + +UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_codepoint_valid(utf8proc_int32_t uc) { + return (((utf8proc_uint32_t)uc)-0xd800 > 0x07ff) && ((utf8proc_uint32_t)uc < 0x110000); +} + +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_encode_char(utf8proc_int32_t uc, utf8proc_uint8_t *dst) { + if (uc < 0x00) { + return 0; + } else if (uc < 0x80) { + dst[0] = (utf8proc_uint8_t) uc; + return 1; + } else if (uc < 0x800) { + dst[0] = (utf8proc_uint8_t)(0xC0 + (uc >> 6)); + dst[1] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F)); + return 2; + // Note: we allow encoding 0xd800-0xdfff here, so as not to change + // the API, however, these are actually invalid in UTF-8 + } else if (uc < 0x10000) { + dst[0] = (utf8proc_uint8_t)(0xE0 + (uc >> 12)); + dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F)); + dst[2] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F)); + return 3; + } else if (uc < 0x110000) { + dst[0] = (utf8proc_uint8_t)(0xF0 + (uc >> 18)); + dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 12) & 0x3F)); + dst[2] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F)); + dst[3] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F)); + return 4; + } else return 0; +} + +/* internal version used for inserting 0xff bytes between graphemes */ +static utf8proc_ssize_t charbound_encode_char(utf8proc_int32_t uc, utf8proc_uint8_t *dst) { + if (uc < 0x00) { + if (uc == -1) { /* internal value used for grapheme breaks */ + dst[0] = (utf8proc_uint8_t)0xFF; + return 1; + } + return 0; + } else if (uc < 0x80) { + dst[0] = (utf8proc_uint8_t)uc; + return 1; + } else if (uc < 0x800) { + dst[0] = (utf8proc_uint8_t)(0xC0 + (uc >> 6)); + dst[1] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F)); + return 2; + } else if (uc < 0x10000) { + dst[0] = (utf8proc_uint8_t)(0xE0 + (uc >> 12)); + dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F)); + dst[2] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F)); + return 3; + } else if (uc < 0x110000) { + dst[0] = (utf8proc_uint8_t)(0xF0 + (uc >> 18)); + dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 12) & 0x3F)); + dst[2] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F)); + dst[3] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F)); + return 4; + } else return 0; +} + +/* internal "unsafe" version that does not check whether uc is in range */ +static const utf8proc_property_t *unsafe_get_property(utf8proc_int32_t uc) { + /* ASSERT: uc >= 0 && uc < 0x110000 */ + return utf8proc_properties + ( + utf8proc_stage2table[ + utf8proc_stage1table[uc >> 8] + (uc & 0xFF) + ] + ); +} + +UTF8PROC_DLLEXPORT const utf8proc_property_t *utf8proc_get_property(utf8proc_int32_t uc) { + return uc < 0 || uc >= 0x110000 ? utf8proc_properties : unsafe_get_property(uc); +} + +/* return whether there is a grapheme break between boundclasses lbc and tbc + (according to the definition of extended grapheme clusters) + + Rule numbering refers to TR29 Version 29 (Unicode 9.0.0): + http://www.unicode.org/reports/tr29/tr29-29.html + + CAVEATS: + Please note that evaluation of GB10 (grapheme breaks between emoji zwj sequences) + and GB 12/13 (regional indicator code points) require knowledge of previous characters + and are thus not handled by this function. This may result in an incorrect break before + an E_Modifier class codepoint and an incorrectly missing break between two + REGIONAL_INDICATOR class code points if such support does not exist in the caller. + + See the special support in grapheme_break_extended, for required bookkeeping by the caller. +*/ +static utf8proc_bool grapheme_break_simple(int lbc, int tbc) { + return + (lbc == UTF8PROC_BOUNDCLASS_START) ? true : // GB1 + (lbc == UTF8PROC_BOUNDCLASS_CR && // GB3 + tbc == UTF8PROC_BOUNDCLASS_LF) ? false : // --- + (lbc >= UTF8PROC_BOUNDCLASS_CR && lbc <= UTF8PROC_BOUNDCLASS_CONTROL) ? true : // GB4 + (tbc >= UTF8PROC_BOUNDCLASS_CR && tbc <= UTF8PROC_BOUNDCLASS_CONTROL) ? true : // GB5 + (lbc == UTF8PROC_BOUNDCLASS_L && // GB6 + (tbc == UTF8PROC_BOUNDCLASS_L || // --- + tbc == UTF8PROC_BOUNDCLASS_V || // --- + tbc == UTF8PROC_BOUNDCLASS_LV || // --- + tbc == UTF8PROC_BOUNDCLASS_LVT)) ? false : // --- + ((lbc == UTF8PROC_BOUNDCLASS_LV || // GB7 + lbc == UTF8PROC_BOUNDCLASS_V) && // --- + (tbc == UTF8PROC_BOUNDCLASS_V || // --- + tbc == UTF8PROC_BOUNDCLASS_T)) ? false : // --- + ((lbc == UTF8PROC_BOUNDCLASS_LVT || // GB8 + lbc == UTF8PROC_BOUNDCLASS_T) && // --- + tbc == UTF8PROC_BOUNDCLASS_T) ? false : // --- + (tbc == UTF8PROC_BOUNDCLASS_EXTEND || // GB9 + tbc == UTF8PROC_BOUNDCLASS_ZWJ || // --- + tbc == UTF8PROC_BOUNDCLASS_SPACINGMARK || // GB9a + lbc == UTF8PROC_BOUNDCLASS_PREPEND) ? false : // GB9b + (lbc == UTF8PROC_BOUNDCLASS_E_ZWG && // GB11 (requires additional handling below) + tbc == UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC) ? false : // ---- + (lbc == UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR && // GB12/13 (requires additional handling below) + tbc == UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR) ? false : // ---- + true; // GB999 +} + +static utf8proc_bool grapheme_break_extended(int lbc, int tbc, utf8proc_int32_t *state) +{ + if (state) { + int lbc_override; + if (*state == UTF8PROC_BOUNDCLASS_START) + *state = lbc_override = lbc; + else + lbc_override = *state; + utf8proc_bool break_permitted = grapheme_break_simple(lbc_override, tbc); + + // Special support for GB 12/13 made possible by GB999. After two RI + // class codepoints we want to force a break. Do this by resetting the + // second RI's bound class to UTF8PROC_BOUNDCLASS_OTHER, to force a break + // after that character according to GB999 (unless of course such a break is + // forbidden by a different rule such as GB9). + if (*state == tbc && tbc == UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR) + *state = UTF8PROC_BOUNDCLASS_OTHER; + // Special support for GB11 (emoji extend* zwj / emoji) + else if (*state == UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC) { + if (tbc == UTF8PROC_BOUNDCLASS_EXTEND) // fold EXTEND codepoints into emoji + *state = UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC; + else if (tbc == UTF8PROC_BOUNDCLASS_ZWJ) + *state = UTF8PROC_BOUNDCLASS_E_ZWG; // state to record emoji+zwg combo + else + *state = tbc; + } + else + *state = tbc; + + return break_permitted; + } + else + return grapheme_break_simple(lbc, tbc); +} + +UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break_stateful( + utf8proc_int32_t c1, utf8proc_int32_t c2, utf8proc_int32_t *state) { + + return grapheme_break_extended(utf8proc_get_property(c1)->boundclass, + utf8proc_get_property(c2)->boundclass, + state); +} + + +UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break( + utf8proc_int32_t c1, utf8proc_int32_t c2) { + return utf8proc_grapheme_break_stateful(c1, c2, NULL); +} + +static utf8proc_int32_t seqindex_decode_entry(const utf8proc_uint16_t **entry) +{ + utf8proc_int32_t entry_cp = **entry; + if ((entry_cp & 0xF800) == 0xD800) { + *entry = *entry + 1; + entry_cp = ((entry_cp & 0x03FF) << 10) | (**entry & 0x03FF); + entry_cp += 0x10000; + } + return entry_cp; +} + +static utf8proc_int32_t seqindex_decode_index(const utf8proc_uint32_t seqindex) +{ + const utf8proc_uint16_t *entry = &utf8proc_sequences[seqindex]; + return seqindex_decode_entry(&entry); +} + +static utf8proc_ssize_t seqindex_write_char_decomposed(utf8proc_uint16_t seqindex, utf8proc_int32_t *dst, utf8proc_ssize_t bufsize, utf8proc_option_t options, int *last_boundclass) { + utf8proc_ssize_t written = 0; + const utf8proc_uint16_t *entry = &utf8proc_sequences[seqindex & 0x3FFF]; + int len = seqindex >> 14; + if (len >= 3) { + len = *entry; + entry++; + } + for (; len >= 0; entry++, len--) { + utf8proc_int32_t entry_cp = seqindex_decode_entry(&entry); + + written += utf8proc_decompose_char(entry_cp, dst+written, + (bufsize > written) ? (bufsize - written) : 0, options, + last_boundclass); + if (written < 0) return UTF8PROC_ERROR_OVERFLOW; + } + return written; +} + +UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_tolower(utf8proc_int32_t c) +{ + utf8proc_int32_t cl = utf8proc_get_property(c)->lowercase_seqindex; + return cl != UINT16_MAX ? seqindex_decode_index((utf8proc_uint32_t)cl) : c; +} + +UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_toupper(utf8proc_int32_t c) +{ + utf8proc_int32_t cu = utf8proc_get_property(c)->uppercase_seqindex; + return cu != UINT16_MAX ? seqindex_decode_index((utf8proc_uint32_t)cu) : c; +} + +UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_totitle(utf8proc_int32_t c) +{ + utf8proc_int32_t cu = utf8proc_get_property(c)->titlecase_seqindex; + return cu != UINT16_MAX ? seqindex_decode_index((utf8proc_uint32_t)cu) : c; +} + +UTF8PROC_DLLEXPORT int utf8proc_islower(utf8proc_int32_t c) +{ + const utf8proc_property_t *p = utf8proc_get_property(c); + return p->lowercase_seqindex != p->uppercase_seqindex && p->lowercase_seqindex == UINT16_MAX; +} + +UTF8PROC_DLLEXPORT int utf8proc_isupper(utf8proc_int32_t c) +{ + const utf8proc_property_t *p = utf8proc_get_property(c); + return p->lowercase_seqindex != p->uppercase_seqindex && p->uppercase_seqindex == UINT16_MAX && p->category != UTF8PROC_CATEGORY_LT; +} + +/* return a character width analogous to wcwidth (except portable and + hopefully less buggy than most system wcwidth functions). */ +UTF8PROC_DLLEXPORT int utf8proc_charwidth(utf8proc_int32_t c) { + return utf8proc_get_property(c)->charwidth; +} + +UTF8PROC_DLLEXPORT utf8proc_category_t utf8proc_category(utf8proc_int32_t c) { + return (utf8proc_category_t) utf8proc_get_property(c)->category; +} + +UTF8PROC_DLLEXPORT const char *utf8proc_category_string(utf8proc_int32_t c) { + static const char s[][3] = {"Cn","Lu","Ll","Lt","Lm","Lo","Mn","Mc","Me","Nd","Nl","No","Pc","Pd","Ps","Pe","Pi","Pf","Po","Sm","Sc","Sk","So","Zs","Zl","Zp","Cc","Cf","Cs","Co"}; + return s[utf8proc_category(c)]; +} + +#define utf8proc_decompose_lump(replacement_uc) \ + return utf8proc_decompose_char((replacement_uc), dst, bufsize, \ + options & ~(unsigned int)UTF8PROC_LUMP, last_boundclass) + +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_char(utf8proc_int32_t uc, utf8proc_int32_t *dst, utf8proc_ssize_t bufsize, utf8proc_option_t options, int *last_boundclass) { + const utf8proc_property_t *property; + utf8proc_propval_t category; + utf8proc_int32_t hangul_sindex; + if (uc < 0 || uc >= 0x110000) return UTF8PROC_ERROR_NOTASSIGNED; + property = unsafe_get_property(uc); + category = property->category; + hangul_sindex = uc - UTF8PROC_HANGUL_SBASE; + if (options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) { + if (hangul_sindex >= 0 && hangul_sindex < UTF8PROC_HANGUL_SCOUNT) { + utf8proc_int32_t hangul_tindex; + if (bufsize >= 1) { + dst[0] = UTF8PROC_HANGUL_LBASE + + hangul_sindex / UTF8PROC_HANGUL_NCOUNT; + if (bufsize >= 2) dst[1] = UTF8PROC_HANGUL_VBASE + + (hangul_sindex % UTF8PROC_HANGUL_NCOUNT) / UTF8PROC_HANGUL_TCOUNT; + } + hangul_tindex = hangul_sindex % UTF8PROC_HANGUL_TCOUNT; + if (!hangul_tindex) return 2; + if (bufsize >= 3) dst[2] = UTF8PROC_HANGUL_TBASE + hangul_tindex; + return 3; + } + } + if (options & UTF8PROC_REJECTNA) { + if (!category) return UTF8PROC_ERROR_NOTASSIGNED; + } + if (options & UTF8PROC_IGNORE) { + if (property->ignorable) return 0; + } + if (options & UTF8PROC_STRIPNA) { + if (!category) return 0; + } + if (options & UTF8PROC_LUMP) { + if (category == UTF8PROC_CATEGORY_ZS) utf8proc_decompose_lump(0x0020); + if (uc == 0x2018 || uc == 0x2019 || uc == 0x02BC || uc == 0x02C8) + utf8proc_decompose_lump(0x0027); + if (category == UTF8PROC_CATEGORY_PD || uc == 0x2212) + utf8proc_decompose_lump(0x002D); + if (uc == 0x2044 || uc == 0x2215) utf8proc_decompose_lump(0x002F); + if (uc == 0x2236) utf8proc_decompose_lump(0x003A); + if (uc == 0x2039 || uc == 0x2329 || uc == 0x3008) + utf8proc_decompose_lump(0x003C); + if (uc == 0x203A || uc == 0x232A || uc == 0x3009) + utf8proc_decompose_lump(0x003E); + if (uc == 0x2216) utf8proc_decompose_lump(0x005C); + if (uc == 0x02C4 || uc == 0x02C6 || uc == 0x2038 || uc == 0x2303) + utf8proc_decompose_lump(0x005E); + if (category == UTF8PROC_CATEGORY_PC || uc == 0x02CD) + utf8proc_decompose_lump(0x005F); + if (uc == 0x02CB) utf8proc_decompose_lump(0x0060); + if (uc == 0x2223) utf8proc_decompose_lump(0x007C); + if (uc == 0x223C) utf8proc_decompose_lump(0x007E); + if ((options & UTF8PROC_NLF2LS) && (options & UTF8PROC_NLF2PS)) { + if (category == UTF8PROC_CATEGORY_ZL || + category == UTF8PROC_CATEGORY_ZP) + utf8proc_decompose_lump(0x000A); + } + } + if (options & UTF8PROC_STRIPMARK) { + if (category == UTF8PROC_CATEGORY_MN || + category == UTF8PROC_CATEGORY_MC || + category == UTF8PROC_CATEGORY_ME) return 0; + } + if (options & UTF8PROC_CASEFOLD) { + if (property->casefold_seqindex != UINT16_MAX) { + return seqindex_write_char_decomposed(property->casefold_seqindex, dst, bufsize, options, last_boundclass); + } + } + if (options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) { + if (property->decomp_seqindex != UINT16_MAX && + (!property->decomp_type || (options & UTF8PROC_COMPAT))) { + return seqindex_write_char_decomposed(property->decomp_seqindex, dst, bufsize, options, last_boundclass); + } + } + if (options & UTF8PROC_CHARBOUND) { + utf8proc_bool boundary; + int tbc = property->boundclass; + boundary = grapheme_break_extended(*last_boundclass, tbc, last_boundclass); + if (boundary) { + if (bufsize >= 1) dst[0] = -1; /* sentinel value for grapheme break */ + if (bufsize >= 2) dst[1] = uc; + return 2; + } + } + if (bufsize >= 1) *dst = uc; + return 1; +} + +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose( + const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, + utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options +) { + return utf8proc_decompose_custom(str, strlen, buffer, bufsize, options, NULL, NULL); +} + +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_custom( + const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, + utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options, + utf8proc_custom_func custom_func, void *custom_data +) { + /* strlen will be ignored, if UTF8PROC_NULLTERM is set in options */ + utf8proc_ssize_t wpos = 0; + if ((options & UTF8PROC_COMPOSE) && (options & UTF8PROC_DECOMPOSE)) + return UTF8PROC_ERROR_INVALIDOPTS; + if ((options & UTF8PROC_STRIPMARK) && + !(options & UTF8PROC_COMPOSE) && !(options & UTF8PROC_DECOMPOSE)) + return UTF8PROC_ERROR_INVALIDOPTS; + { + utf8proc_int32_t uc; + utf8proc_ssize_t rpos = 0; + utf8proc_ssize_t decomp_result; + int boundclass = UTF8PROC_BOUNDCLASS_START; + while (1) { + if (options & UTF8PROC_NULLTERM) { + rpos += utf8proc_iterate(str + rpos, -1, &uc); + /* checking of return value is not necessary, + as 'uc' is < 0 in case of error */ + if (uc < 0) return UTF8PROC_ERROR_INVALIDUTF8; + if (rpos < 0) return UTF8PROC_ERROR_OVERFLOW; + if (uc == 0) break; + } else { + if (rpos >= strlen) break; + rpos += utf8proc_iterate(str + rpos, strlen - rpos, &uc); + if (uc < 0) return UTF8PROC_ERROR_INVALIDUTF8; + } + if (custom_func != NULL) { + uc = custom_func(uc, custom_data); /* user-specified custom mapping */ + } + decomp_result = utf8proc_decompose_char( + uc, buffer + wpos, (bufsize > wpos) ? (bufsize - wpos) : 0, options, + &boundclass + ); + if (decomp_result < 0) return decomp_result; + wpos += decomp_result; + /* prohibiting integer overflows due to too long strings: */ + if (wpos < 0 || + wpos > (utf8proc_ssize_t)(SSIZE_MAX/sizeof(utf8proc_int32_t)/2)) + return UTF8PROC_ERROR_OVERFLOW; + } + } + if ((options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) && bufsize >= wpos) { + utf8proc_ssize_t pos = 0; + while (pos < wpos-1) { + utf8proc_int32_t uc1, uc2; + const utf8proc_property_t *property1, *property2; + uc1 = buffer[pos]; + uc2 = buffer[pos+1]; + property1 = unsafe_get_property(uc1); + property2 = unsafe_get_property(uc2); + if (property1->combining_class > property2->combining_class && + property2->combining_class > 0) { + buffer[pos] = uc2; + buffer[pos+1] = uc1; + if (pos > 0) pos--; else pos++; + } else { + pos++; + } + } + } + return wpos; +} + +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_normalize_utf32(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options) { + /* UTF8PROC_NULLTERM option will be ignored, 'length' is never ignored */ + if (options & (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS | UTF8PROC_STRIPCC)) { + utf8proc_ssize_t rpos; + utf8proc_ssize_t wpos = 0; + utf8proc_int32_t uc; + for (rpos = 0; rpos < length; rpos++) { + uc = buffer[rpos]; + if (uc == 0x000D && rpos < length-1 && buffer[rpos+1] == 0x000A) rpos++; + if (uc == 0x000A || uc == 0x000D || uc == 0x0085 || + ((options & UTF8PROC_STRIPCC) && (uc == 0x000B || uc == 0x000C))) { + if (options & UTF8PROC_NLF2LS) { + if (options & UTF8PROC_NLF2PS) { + buffer[wpos++] = 0x000A; + } else { + buffer[wpos++] = 0x2028; + } + } else { + if (options & UTF8PROC_NLF2PS) { + buffer[wpos++] = 0x2029; + } else { + buffer[wpos++] = 0x0020; + } + } + } else if ((options & UTF8PROC_STRIPCC) && + (uc < 0x0020 || (uc >= 0x007F && uc < 0x00A0))) { + if (uc == 0x0009) buffer[wpos++] = 0x0020; + } else { + buffer[wpos++] = uc; + } + } + length = wpos; + } + if (options & UTF8PROC_COMPOSE) { + utf8proc_int32_t *starter = NULL; + utf8proc_int32_t current_char; + const utf8proc_property_t *starter_property = NULL, *current_property; + utf8proc_propval_t max_combining_class = -1; + utf8proc_ssize_t rpos; + utf8proc_ssize_t wpos = 0; + utf8proc_int32_t composition; + for (rpos = 0; rpos < length; rpos++) { + current_char = buffer[rpos]; + current_property = unsafe_get_property(current_char); + if (starter && current_property->combining_class > max_combining_class) { + /* combination perhaps possible */ + utf8proc_int32_t hangul_lindex; + utf8proc_int32_t hangul_sindex; + hangul_lindex = *starter - UTF8PROC_HANGUL_LBASE; + if (hangul_lindex >= 0 && hangul_lindex < UTF8PROC_HANGUL_LCOUNT) { + utf8proc_int32_t hangul_vindex; + hangul_vindex = current_char - UTF8PROC_HANGUL_VBASE; + if (hangul_vindex >= 0 && hangul_vindex < UTF8PROC_HANGUL_VCOUNT) { + *starter = UTF8PROC_HANGUL_SBASE + + (hangul_lindex * UTF8PROC_HANGUL_VCOUNT + hangul_vindex) * + UTF8PROC_HANGUL_TCOUNT; + starter_property = NULL; + continue; + } + } + hangul_sindex = *starter - UTF8PROC_HANGUL_SBASE; + if (hangul_sindex >= 0 && hangul_sindex < UTF8PROC_HANGUL_SCOUNT && + (hangul_sindex % UTF8PROC_HANGUL_TCOUNT) == 0) { + utf8proc_int32_t hangul_tindex; + hangul_tindex = current_char - UTF8PROC_HANGUL_TBASE; + if (hangul_tindex >= 0 && hangul_tindex < UTF8PROC_HANGUL_TCOUNT) { + *starter += hangul_tindex; + starter_property = NULL; + continue; + } + } + if (!starter_property) { + starter_property = unsafe_get_property(*starter); + } + if (starter_property->comb_index < 0x8000 && + current_property->comb_index != UINT16_MAX && + current_property->comb_index >= 0x8000) { + int sidx = starter_property->comb_index; + int idx = current_property->comb_index & 0x3FFF; + if (idx >= utf8proc_combinations[sidx] && idx <= utf8proc_combinations[sidx + 1] ) { + idx += sidx + 2 - utf8proc_combinations[sidx]; + if (current_property->comb_index & 0x4000) { + composition = (utf8proc_combinations[idx] << 16) | utf8proc_combinations[idx+1]; + } else + composition = utf8proc_combinations[idx]; + + if (composition > 0 && (!(options & UTF8PROC_STABLE) || + !(unsafe_get_property(composition)->comp_exclusion))) { + *starter = composition; + starter_property = NULL; + continue; + } + } + } + } + buffer[wpos] = current_char; + if (current_property->combining_class) { + if (current_property->combining_class > max_combining_class) { + max_combining_class = current_property->combining_class; + } + } else { + starter = buffer + wpos; + starter_property = NULL; + max_combining_class = -1; + } + wpos++; + } + length = wpos; + } + return length; +} + +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_reencode(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options) { + /* UTF8PROC_NULLTERM option will be ignored, 'length' is never ignored + ASSERT: 'buffer' has one spare byte of free space at the end! */ + length = utf8proc_normalize_utf32(buffer, length, options); + if (length < 0) return length; + { + utf8proc_ssize_t rpos, wpos = 0; + utf8proc_int32_t uc; + if (options & UTF8PROC_CHARBOUND) { + for (rpos = 0; rpos < length; rpos++) { + uc = buffer[rpos]; + wpos += charbound_encode_char(uc, ((utf8proc_uint8_t *)buffer) + wpos); + } + } else { + for (rpos = 0; rpos < length; rpos++) { + uc = buffer[rpos]; + wpos += utf8proc_encode_char(uc, ((utf8proc_uint8_t *)buffer) + wpos); + } + } + ((utf8proc_uint8_t *)buffer)[wpos] = 0; + return wpos; + } +} + +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map( + const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options +) { + return utf8proc_map_custom(str, strlen, dstptr, options, NULL, NULL); +} + +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map_custom( + const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options, + utf8proc_custom_func custom_func, void *custom_data +) { + utf8proc_int32_t *buffer; + utf8proc_ssize_t result; + *dstptr = NULL; + result = utf8proc_decompose_custom(str, strlen, NULL, 0, options, custom_func, custom_data); + if (result < 0) return result; + buffer = (utf8proc_int32_t *) malloc(((utf8proc_size_t)result) * sizeof(utf8proc_int32_t) + 1); + if (!buffer) return UTF8PROC_ERROR_NOMEM; + result = utf8proc_decompose_custom(str, strlen, buffer, result, options, custom_func, custom_data); + if (result < 0) { + free(buffer); + return result; + } + result = utf8proc_reencode(buffer, result, options); + if (result < 0) { + free(buffer); + return result; + } + { + utf8proc_int32_t *newptr; + newptr = (utf8proc_int32_t *) realloc(buffer, (size_t)result+1); + if (newptr) buffer = newptr; + } + *dstptr = (utf8proc_uint8_t *)buffer; + return result; +} + +UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFD(const utf8proc_uint8_t *str) { + utf8proc_uint8_t *retval; + utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE | + UTF8PROC_DECOMPOSE); + return retval; +} + +UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFC(const utf8proc_uint8_t *str) { + utf8proc_uint8_t *retval; + utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE | + UTF8PROC_COMPOSE); + return retval; +} + +UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKD(const utf8proc_uint8_t *str) { + utf8proc_uint8_t *retval; + utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE | + UTF8PROC_DECOMPOSE | UTF8PROC_COMPAT); + return retval; +} + +UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC(const utf8proc_uint8_t *str) { + utf8proc_uint8_t *retval; + utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE | + UTF8PROC_COMPOSE | UTF8PROC_COMPAT); + return retval; +} + +UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC_Casefold(const utf8proc_uint8_t *str) { + utf8proc_uint8_t *retval; + utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE | + UTF8PROC_COMPOSE | UTF8PROC_COMPAT | UTF8PROC_CASEFOLD | UTF8PROC_IGNORE); + return retval; +} diff --git a/src/utf8proc/utf8proc.h b/src/utf8proc/utf8proc.h new file mode 100644 index 00000000..7ec591d3 --- /dev/null +++ b/src/utf8proc/utf8proc.h @@ -0,0 +1,733 @@ +/* + * Copyright (c) 2014-2021 Steven G. Johnson, Jiahao Chen, Peter Colberg, Tony Kelman, Scott P. Jones, and other contributors. + * Copyright (c) 2009 Public Software Group e. V., Berlin, Germany + * + * 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. + */ + + +/** + * @mainpage + * + * utf8proc is a free/open-source (MIT/expat licensed) C library + * providing Unicode normalization, case-folding, and other operations + * for strings in the UTF-8 encoding, supporting up-to-date Unicode versions. + * See the utf8proc home page (http://julialang.org/utf8proc/) + * for downloads and other information, or the source code on github + * (https://github.com/JuliaLang/utf8proc). + * + * For the utf8proc API documentation, see: @ref utf8proc.h + * + * The features of utf8proc include: + * + * - Transformation of strings (@ref utf8proc_map) to: + * - decompose (@ref UTF8PROC_DECOMPOSE) or compose (@ref UTF8PROC_COMPOSE) Unicode combining characters (http://en.wikipedia.org/wiki/Combining_character) + * - canonicalize Unicode compatibility characters (@ref UTF8PROC_COMPAT) + * - strip "ignorable" (@ref UTF8PROC_IGNORE) characters, control characters (@ref UTF8PROC_STRIPCC), or combining characters such as accents (@ref UTF8PROC_STRIPMARK) + * - case-folding (@ref UTF8PROC_CASEFOLD) + * - Unicode normalization: @ref utf8proc_NFD, @ref utf8proc_NFC, @ref utf8proc_NFKD, @ref utf8proc_NFKC + * - Detecting grapheme boundaries (@ref utf8proc_grapheme_break and @ref UTF8PROC_CHARBOUND) + * - Character-width computation: @ref utf8proc_charwidth + * - Classification of characters by Unicode category: @ref utf8proc_category and @ref utf8proc_category_string + * - Encode (@ref utf8proc_encode_char) and decode (@ref utf8proc_iterate) Unicode codepoints to/from UTF-8. + */ + +/** @file */ + +#ifndef UTF8PROC_H +#define UTF8PROC_H + +/** @name API version + * + * The utf8proc API version MAJOR.MINOR.PATCH, following + * semantic-versioning rules (http://semver.org) based on API + * compatibility. + * + * This is also returned at runtime by @ref utf8proc_version; however, the + * runtime version may append a string like "-dev" to the version number + * for prerelease versions. + * + * @note The shared-library version number in the Makefile + * (and CMakeLists.txt, and MANIFEST) may be different, + * being based on ABI compatibility rather than API compatibility. + */ +/** @{ */ +/** The MAJOR version number (increased when backwards API compatibility is broken). */ +#define UTF8PROC_VERSION_MAJOR 2 +/** The MINOR version number (increased when new functionality is added in a backwards-compatible manner). */ +#define UTF8PROC_VERSION_MINOR 8 +/** The PATCH version (increased for fixes that do not change the API). */ +#define UTF8PROC_VERSION_PATCH 0 +/** @} */ + +#include + +#if defined(_MSC_VER) && _MSC_VER < 1800 +// MSVC prior to 2013 lacked stdbool.h and inttypes.h +typedef signed char utf8proc_int8_t; +typedef unsigned char utf8proc_uint8_t; +typedef short utf8proc_int16_t; +typedef unsigned short utf8proc_uint16_t; +typedef int utf8proc_int32_t; +typedef unsigned int utf8proc_uint32_t; +# ifdef _WIN64 +typedef __int64 utf8proc_ssize_t; +typedef unsigned __int64 utf8proc_size_t; +# else +typedef int utf8proc_ssize_t; +typedef unsigned int utf8proc_size_t; +# endif +# ifndef __cplusplus +// emulate C99 bool +typedef unsigned char utf8proc_bool; +# ifndef __bool_true_false_are_defined +# define false 0 +# define true 1 +# define __bool_true_false_are_defined 1 +# endif +# else +typedef bool utf8proc_bool; +# endif +#else +# include +# include +# include +typedef int8_t utf8proc_int8_t; +typedef uint8_t utf8proc_uint8_t; +typedef int16_t utf8proc_int16_t; +typedef uint16_t utf8proc_uint16_t; +typedef int32_t utf8proc_int32_t; +typedef uint32_t utf8proc_uint32_t; +typedef size_t utf8proc_size_t; +typedef ptrdiff_t utf8proc_ssize_t; +typedef bool utf8proc_bool; +#endif +#include + +#ifdef UTF8PROC_STATIC +# define UTF8PROC_DLLEXPORT +#else +# ifdef _WIN32 +# ifdef UTF8PROC_EXPORTS +# define UTF8PROC_DLLEXPORT __declspec(dllexport) +# else +# define UTF8PROC_DLLEXPORT __declspec(dllimport) +# endif +# elif __GNUC__ >= 4 +# define UTF8PROC_DLLEXPORT __attribute__ ((visibility("default"))) +# else +# define UTF8PROC_DLLEXPORT +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Option flags used by several functions in the library. + */ +typedef enum { + /** The given UTF-8 input is NULL terminated. */ + UTF8PROC_NULLTERM = (1<<0), + /** Unicode Versioning Stability has to be respected. */ + UTF8PROC_STABLE = (1<<1), + /** Compatibility decomposition (i.e. formatting information is lost). */ + UTF8PROC_COMPAT = (1<<2), + /** Return a result with decomposed characters. */ + UTF8PROC_COMPOSE = (1<<3), + /** Return a result with decomposed characters. */ + UTF8PROC_DECOMPOSE = (1<<4), + /** Strip "default ignorable characters" such as SOFT-HYPHEN or ZERO-WIDTH-SPACE. */ + UTF8PROC_IGNORE = (1<<5), + /** Return an error, if the input contains unassigned codepoints. */ + UTF8PROC_REJECTNA = (1<<6), + /** + * Indicating that NLF-sequences (LF, CRLF, CR, NEL) are representing a + * line break, and should be converted to the codepoint for line + * separation (LS). + */ + UTF8PROC_NLF2LS = (1<<7), + /** + * Indicating that NLF-sequences are representing a paragraph break, and + * should be converted to the codepoint for paragraph separation + * (PS). + */ + UTF8PROC_NLF2PS = (1<<8), + /** Indicating that the meaning of NLF-sequences is unknown. */ + UTF8PROC_NLF2LF = (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS), + /** Strips and/or convers control characters. + * + * NLF-sequences are transformed into space, except if one of the + * NLF2LS/PS/LF options is given. HorizontalTab (HT) and FormFeed (FF) + * are treated as a NLF-sequence in this case. All other control + * characters are simply removed. + */ + UTF8PROC_STRIPCC = (1<<9), + /** + * Performs unicode case folding, to be able to do a case-insensitive + * string comparison. + */ + UTF8PROC_CASEFOLD = (1<<10), + /** + * Inserts 0xFF bytes at the beginning of each sequence which is + * representing a single grapheme cluster (see UAX#29). + */ + UTF8PROC_CHARBOUND = (1<<11), + /** Lumps certain characters together. + * + * E.g. HYPHEN U+2010 and MINUS U+2212 to ASCII "-". See lump.md for details. + * + * If NLF2LF is set, this includes a transformation of paragraph and + * line separators to ASCII line-feed (LF). + */ + UTF8PROC_LUMP = (1<<12), + /** Strips all character markings. + * + * This includes non-spacing, spacing and enclosing (i.e. accents). + * @note This option works only with @ref UTF8PROC_COMPOSE or + * @ref UTF8PROC_DECOMPOSE + */ + UTF8PROC_STRIPMARK = (1<<13), + /** + * Strip unassigned codepoints. + */ + UTF8PROC_STRIPNA = (1<<14), +} utf8proc_option_t; + +/** @name Error codes + * Error codes being returned by almost all functions. + */ +/** @{ */ +/** Memory could not be allocated. */ +#define UTF8PROC_ERROR_NOMEM -1 +/** The given string is too long to be processed. */ +#define UTF8PROC_ERROR_OVERFLOW -2 +/** The given string is not a legal UTF-8 string. */ +#define UTF8PROC_ERROR_INVALIDUTF8 -3 +/** The @ref UTF8PROC_REJECTNA flag was set and an unassigned codepoint was found. */ +#define UTF8PROC_ERROR_NOTASSIGNED -4 +/** Invalid options have been used. */ +#define UTF8PROC_ERROR_INVALIDOPTS -5 +/** @} */ + +/* @name Types */ + +/** Holds the value of a property. */ +typedef utf8proc_int16_t utf8proc_propval_t; + +/** Struct containing information about a codepoint. */ +typedef struct utf8proc_property_struct { + /** + * Unicode category. + * @see utf8proc_category_t. + */ + utf8proc_propval_t category; + utf8proc_propval_t combining_class; + /** + * Bidirectional class. + * @see utf8proc_bidi_class_t. + */ + utf8proc_propval_t bidi_class; + /** + * @anchor Decomposition type. + * @see utf8proc_decomp_type_t. + */ + utf8proc_propval_t decomp_type; + utf8proc_uint16_t decomp_seqindex; + utf8proc_uint16_t casefold_seqindex; + utf8proc_uint16_t uppercase_seqindex; + utf8proc_uint16_t lowercase_seqindex; + utf8proc_uint16_t titlecase_seqindex; + utf8proc_uint16_t comb_index; + unsigned bidi_mirrored:1; + unsigned comp_exclusion:1; + /** + * Can this codepoint be ignored? + * + * Used by @ref utf8proc_decompose_char when @ref UTF8PROC_IGNORE is + * passed as an option. + */ + unsigned ignorable:1; + unsigned control_boundary:1; + /** The width of the codepoint. */ + unsigned charwidth:2; + unsigned pad:2; + /** + * Boundclass. + * @see utf8proc_boundclass_t. + */ + unsigned boundclass:8; +} utf8proc_property_t; + +/** Unicode categories. */ +typedef enum { + UTF8PROC_CATEGORY_CN = 0, /**< Other, not assigned */ + UTF8PROC_CATEGORY_LU = 1, /**< Letter, uppercase */ + UTF8PROC_CATEGORY_LL = 2, /**< Letter, lowercase */ + UTF8PROC_CATEGORY_LT = 3, /**< Letter, titlecase */ + UTF8PROC_CATEGORY_LM = 4, /**< Letter, modifier */ + UTF8PROC_CATEGORY_LO = 5, /**< Letter, other */ + UTF8PROC_CATEGORY_MN = 6, /**< Mark, nonspacing */ + UTF8PROC_CATEGORY_MC = 7, /**< Mark, spacing combining */ + UTF8PROC_CATEGORY_ME = 8, /**< Mark, enclosing */ + UTF8PROC_CATEGORY_ND = 9, /**< Number, decimal digit */ + UTF8PROC_CATEGORY_NL = 10, /**< Number, letter */ + UTF8PROC_CATEGORY_NO = 11, /**< Number, other */ + UTF8PROC_CATEGORY_PC = 12, /**< Punctuation, connector */ + UTF8PROC_CATEGORY_PD = 13, /**< Punctuation, dash */ + UTF8PROC_CATEGORY_PS = 14, /**< Punctuation, open */ + UTF8PROC_CATEGORY_PE = 15, /**< Punctuation, close */ + UTF8PROC_CATEGORY_PI = 16, /**< Punctuation, initial quote */ + UTF8PROC_CATEGORY_PF = 17, /**< Punctuation, final quote */ + UTF8PROC_CATEGORY_PO = 18, /**< Punctuation, other */ + UTF8PROC_CATEGORY_SM = 19, /**< Symbol, math */ + UTF8PROC_CATEGORY_SC = 20, /**< Symbol, currency */ + UTF8PROC_CATEGORY_SK = 21, /**< Symbol, modifier */ + UTF8PROC_CATEGORY_SO = 22, /**< Symbol, other */ + UTF8PROC_CATEGORY_ZS = 23, /**< Separator, space */ + UTF8PROC_CATEGORY_ZL = 24, /**< Separator, line */ + UTF8PROC_CATEGORY_ZP = 25, /**< Separator, paragraph */ + UTF8PROC_CATEGORY_CC = 26, /**< Other, control */ + UTF8PROC_CATEGORY_CF = 27, /**< Other, format */ + UTF8PROC_CATEGORY_CS = 28, /**< Other, surrogate */ + UTF8PROC_CATEGORY_CO = 29, /**< Other, private use */ +} utf8proc_category_t; + +/** Bidirectional character classes. */ +typedef enum { + UTF8PROC_BIDI_CLASS_L = 1, /**< Left-to-Right */ + UTF8PROC_BIDI_CLASS_LRE = 2, /**< Left-to-Right Embedding */ + UTF8PROC_BIDI_CLASS_LRO = 3, /**< Left-to-Right Override */ + UTF8PROC_BIDI_CLASS_R = 4, /**< Right-to-Left */ + UTF8PROC_BIDI_CLASS_AL = 5, /**< Right-to-Left Arabic */ + UTF8PROC_BIDI_CLASS_RLE = 6, /**< Right-to-Left Embedding */ + UTF8PROC_BIDI_CLASS_RLO = 7, /**< Right-to-Left Override */ + UTF8PROC_BIDI_CLASS_PDF = 8, /**< Pop Directional Format */ + UTF8PROC_BIDI_CLASS_EN = 9, /**< European Number */ + UTF8PROC_BIDI_CLASS_ES = 10, /**< European Separator */ + UTF8PROC_BIDI_CLASS_ET = 11, /**< European Number Terminator */ + UTF8PROC_BIDI_CLASS_AN = 12, /**< Arabic Number */ + UTF8PROC_BIDI_CLASS_CS = 13, /**< Common Number Separator */ + UTF8PROC_BIDI_CLASS_NSM = 14, /**< Nonspacing Mark */ + UTF8PROC_BIDI_CLASS_BN = 15, /**< Boundary Neutral */ + UTF8PROC_BIDI_CLASS_B = 16, /**< Paragraph Separator */ + UTF8PROC_BIDI_CLASS_S = 17, /**< Segment Separator */ + UTF8PROC_BIDI_CLASS_WS = 18, /**< Whitespace */ + UTF8PROC_BIDI_CLASS_ON = 19, /**< Other Neutrals */ + UTF8PROC_BIDI_CLASS_LRI = 20, /**< Left-to-Right Isolate */ + UTF8PROC_BIDI_CLASS_RLI = 21, /**< Right-to-Left Isolate */ + UTF8PROC_BIDI_CLASS_FSI = 22, /**< First Strong Isolate */ + UTF8PROC_BIDI_CLASS_PDI = 23, /**< Pop Directional Isolate */ +} utf8proc_bidi_class_t; + +/** Decomposition type. */ +typedef enum { + UTF8PROC_DECOMP_TYPE_FONT = 1, /**< Font */ + UTF8PROC_DECOMP_TYPE_NOBREAK = 2, /**< Nobreak */ + UTF8PROC_DECOMP_TYPE_INITIAL = 3, /**< Initial */ + UTF8PROC_DECOMP_TYPE_MEDIAL = 4, /**< Medial */ + UTF8PROC_DECOMP_TYPE_FINAL = 5, /**< Final */ + UTF8PROC_DECOMP_TYPE_ISOLATED = 6, /**< Isolated */ + UTF8PROC_DECOMP_TYPE_CIRCLE = 7, /**< Circle */ + UTF8PROC_DECOMP_TYPE_SUPER = 8, /**< Super */ + UTF8PROC_DECOMP_TYPE_SUB = 9, /**< Sub */ + UTF8PROC_DECOMP_TYPE_VERTICAL = 10, /**< Vertical */ + UTF8PROC_DECOMP_TYPE_WIDE = 11, /**< Wide */ + UTF8PROC_DECOMP_TYPE_NARROW = 12, /**< Narrow */ + UTF8PROC_DECOMP_TYPE_SMALL = 13, /**< Small */ + UTF8PROC_DECOMP_TYPE_SQUARE = 14, /**< Square */ + UTF8PROC_DECOMP_TYPE_FRACTION = 15, /**< Fraction */ + UTF8PROC_DECOMP_TYPE_COMPAT = 16, /**< Compat */ +} utf8proc_decomp_type_t; + +/** Boundclass property. (TR29) */ +typedef enum { + UTF8PROC_BOUNDCLASS_START = 0, /**< Start */ + UTF8PROC_BOUNDCLASS_OTHER = 1, /**< Other */ + UTF8PROC_BOUNDCLASS_CR = 2, /**< Cr */ + UTF8PROC_BOUNDCLASS_LF = 3, /**< Lf */ + UTF8PROC_BOUNDCLASS_CONTROL = 4, /**< Control */ + UTF8PROC_BOUNDCLASS_EXTEND = 5, /**< Extend */ + UTF8PROC_BOUNDCLASS_L = 6, /**< L */ + UTF8PROC_BOUNDCLASS_V = 7, /**< V */ + UTF8PROC_BOUNDCLASS_T = 8, /**< T */ + UTF8PROC_BOUNDCLASS_LV = 9, /**< Lv */ + UTF8PROC_BOUNDCLASS_LVT = 10, /**< Lvt */ + UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR = 11, /**< Regional indicator */ + UTF8PROC_BOUNDCLASS_SPACINGMARK = 12, /**< Spacingmark */ + UTF8PROC_BOUNDCLASS_PREPEND = 13, /**< Prepend */ + UTF8PROC_BOUNDCLASS_ZWJ = 14, /**< Zero Width Joiner */ + + /* the following are no longer used in Unicode 11, but we keep + the constants here for backward compatibility */ + UTF8PROC_BOUNDCLASS_E_BASE = 15, /**< Emoji Base */ + UTF8PROC_BOUNDCLASS_E_MODIFIER = 16, /**< Emoji Modifier */ + UTF8PROC_BOUNDCLASS_GLUE_AFTER_ZWJ = 17, /**< Glue_After_ZWJ */ + UTF8PROC_BOUNDCLASS_E_BASE_GAZ = 18, /**< E_BASE + GLUE_AFTER_ZJW */ + + /* the Extended_Pictographic property is used in the Unicode 11 + grapheme-boundary rules, so we store it in the boundclass field */ + UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC = 19, + UTF8PROC_BOUNDCLASS_E_ZWG = 20, /* UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC + ZWJ */ +} utf8proc_boundclass_t; + +/** + * Function pointer type passed to @ref utf8proc_map_custom and + * @ref utf8proc_decompose_custom, which is used to specify a user-defined + * mapping of codepoints to be applied in conjunction with other mappings. + */ +typedef utf8proc_int32_t (*utf8proc_custom_func)(utf8proc_int32_t codepoint, void *data); + +/** + * Array containing the byte lengths of a UTF-8 encoded codepoint based + * on the first byte. + */ +UTF8PROC_DLLEXPORT extern const utf8proc_int8_t utf8proc_utf8class[256]; + +/** + * Returns the utf8proc API version as a string MAJOR.MINOR.PATCH + * (http://semver.org format), possibly with a "-dev" suffix for + * development versions. + */ +UTF8PROC_DLLEXPORT const char *utf8proc_version(void); + +/** + * Returns the utf8proc supported Unicode version as a string MAJOR.MINOR.PATCH. + */ +UTF8PROC_DLLEXPORT const char *utf8proc_unicode_version(void); + +/** + * Returns an informative error string for the given utf8proc error code + * (e.g. the error codes returned by @ref utf8proc_map). + */ +UTF8PROC_DLLEXPORT const char *utf8proc_errmsg(utf8proc_ssize_t errcode); + +/** + * Reads a single codepoint from the UTF-8 sequence being pointed to by `str`. + * The maximum number of bytes read is `strlen`, unless `strlen` is + * negative (in which case up to 4 bytes are read). + * + * If a valid codepoint could be read, it is stored in the variable + * pointed to by `codepoint_ref`, otherwise that variable will be set to -1. + * In case of success, the number of bytes read is returned; otherwise, a + * negative error code is returned. + */ +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_iterate(const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_int32_t *codepoint_ref); + +/** + * Check if a codepoint is valid (regardless of whether it has been + * assigned a value by the current Unicode standard). + * + * @return 1 if the given `codepoint` is valid and otherwise return 0. + */ +UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_codepoint_valid(utf8proc_int32_t codepoint); + +/** + * Encodes the codepoint as an UTF-8 string in the byte array pointed + * to by `dst`. This array must be at least 4 bytes long. + * + * In case of success the number of bytes written is returned, and + * otherwise 0 is returned. + * + * This function does not check whether `codepoint` is valid Unicode. + */ +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_encode_char(utf8proc_int32_t codepoint, utf8proc_uint8_t *dst); + +/** + * Look up the properties for a given codepoint. + * + * @param codepoint The Unicode codepoint. + * + * @returns + * A pointer to a (constant) struct containing information about + * the codepoint. + * @par + * If the codepoint is unassigned or invalid, a pointer to a special struct is + * returned in which `category` is 0 (@ref UTF8PROC_CATEGORY_CN). + */ +UTF8PROC_DLLEXPORT const utf8proc_property_t *utf8proc_get_property(utf8proc_int32_t codepoint); + +/** Decompose a codepoint into an array of codepoints. + * + * @param codepoint the codepoint. + * @param dst the destination buffer. + * @param bufsize the size of the destination buffer. + * @param options one or more of the following flags: + * - @ref UTF8PROC_REJECTNA - return an error `codepoint` is unassigned + * - @ref UTF8PROC_IGNORE - strip "default ignorable" codepoints + * - @ref UTF8PROC_CASEFOLD - apply Unicode casefolding + * - @ref UTF8PROC_COMPAT - replace certain codepoints with their + * compatibility decomposition + * - @ref UTF8PROC_CHARBOUND - insert 0xFF bytes before each grapheme cluster + * - @ref UTF8PROC_LUMP - lump certain different codepoints together + * - @ref UTF8PROC_STRIPMARK - remove all character marks + * - @ref UTF8PROC_STRIPNA - remove unassigned codepoints + * @param last_boundclass + * Pointer to an integer variable containing + * the previous codepoint's boundary class if the @ref UTF8PROC_CHARBOUND + * option is used. Otherwise, this parameter is ignored. + * + * @return + * In case of success, the number of codepoints written is returned; in case + * of an error, a negative error code is returned (@ref utf8proc_errmsg). + * @par + * If the number of written codepoints would be bigger than `bufsize`, the + * required buffer size is returned, while the buffer will be overwritten with + * undefined data. + */ +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_char( + utf8proc_int32_t codepoint, utf8proc_int32_t *dst, utf8proc_ssize_t bufsize, + utf8proc_option_t options, int *last_boundclass +); + +/** + * The same as @ref utf8proc_decompose_char, but acts on a whole UTF-8 + * string and orders the decomposed sequences correctly. + * + * If the @ref UTF8PROC_NULLTERM flag in `options` is set, processing + * will be stopped, when a NULL byte is encountered, otherwise `strlen` + * bytes are processed. The result (in the form of 32-bit unicode + * codepoints) is written into the buffer being pointed to by + * `buffer` (which must contain at least `bufsize` entries). In case of + * success, the number of codepoints written is returned; in case of an + * error, a negative error code is returned (@ref utf8proc_errmsg). + * See @ref utf8proc_decompose_custom to supply additional transformations. + * + * If the number of written codepoints would be bigger than `bufsize`, the + * required buffer size is returned, while the buffer will be overwritten with + * undefined data. + */ +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose( + const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, + utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options +); + +/** + * The same as @ref utf8proc_decompose, but also takes a `custom_func` mapping function + * that is called on each codepoint in `str` before any other transformations + * (along with a `custom_data` pointer that is passed through to `custom_func`). + * The `custom_func` argument is ignored if it is `NULL`. See also @ref utf8proc_map_custom. + */ +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_custom( + const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, + utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options, + utf8proc_custom_func custom_func, void *custom_data +); + +/** + * Normalizes the sequence of `length` codepoints pointed to by `buffer` + * in-place (i.e., the result is also stored in `buffer`). + * + * @param buffer the (native-endian UTF-32) unicode codepoints to re-encode. + * @param length the length (in codepoints) of the buffer. + * @param options a bitwise or (`|`) of one or more of the following flags: + * - @ref UTF8PROC_NLF2LS - convert LF, CRLF, CR and NEL into LS + * - @ref UTF8PROC_NLF2PS - convert LF, CRLF, CR and NEL into PS + * - @ref UTF8PROC_NLF2LF - convert LF, CRLF, CR and NEL into LF + * - @ref UTF8PROC_STRIPCC - strip or convert all non-affected control characters + * - @ref UTF8PROC_COMPOSE - try to combine decomposed codepoints into composite + * codepoints + * - @ref UTF8PROC_STABLE - prohibit combining characters that would violate + * the unicode versioning stability + * + * @return + * In case of success, the length (in codepoints) of the normalized UTF-32 string is + * returned; otherwise, a negative error code is returned (@ref utf8proc_errmsg). + * + * @warning The entries of the array pointed to by `str` have to be in the + * range `0x0000` to `0x10FFFF`. Otherwise, the program might crash! + */ +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_normalize_utf32(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options); + +/** + * Reencodes the sequence of `length` codepoints pointed to by `buffer` + * UTF-8 data in-place (i.e., the result is also stored in `buffer`). + * Can optionally normalize the UTF-32 sequence prior to UTF-8 conversion. + * + * @param buffer the (native-endian UTF-32) unicode codepoints to re-encode. + * @param length the length (in codepoints) of the buffer. + * @param options a bitwise or (`|`) of one or more of the following flags: + * - @ref UTF8PROC_NLF2LS - convert LF, CRLF, CR and NEL into LS + * - @ref UTF8PROC_NLF2PS - convert LF, CRLF, CR and NEL into PS + * - @ref UTF8PROC_NLF2LF - convert LF, CRLF, CR and NEL into LF + * - @ref UTF8PROC_STRIPCC - strip or convert all non-affected control characters + * - @ref UTF8PROC_COMPOSE - try to combine decomposed codepoints into composite + * codepoints + * - @ref UTF8PROC_STABLE - prohibit combining characters that would violate + * the unicode versioning stability + * - @ref UTF8PROC_CHARBOUND - insert 0xFF bytes before each grapheme cluster + * + * @return + * In case of success, the length (in bytes) of the resulting nul-terminated + * UTF-8 string is returned; otherwise, a negative error code is returned + * (@ref utf8proc_errmsg). + * + * @warning The amount of free space pointed to by `buffer` must + * exceed the amount of the input data by one byte, and the + * entries of the array pointed to by `str` have to be in the + * range `0x0000` to `0x10FFFF`. Otherwise, the program might crash! + */ +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_reencode(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options); + +/** + * Given a pair of consecutive codepoints, return whether a grapheme break is + * permitted between them (as defined by the extended grapheme clusters in UAX#29). + * + * @param codepoint1 The first codepoint. + * @param codepoint2 The second codepoint, occurring consecutively after `codepoint1`. + * @param state Beginning with Version 29 (Unicode 9.0.0), this algorithm requires + * state to break graphemes. This state can be passed in as a pointer + * in the `state` argument and should initially be set to 0. If the + * state is not passed in (i.e. a null pointer is passed), UAX#29 rules + * GB10/12/13 which require this state will not be applied, essentially + * matching the rules in Unicode 8.0.0. + * + * @warning If the state parameter is used, `utf8proc_grapheme_break_stateful` must + * be called IN ORDER on ALL potential breaks in a string. However, it + * is safe to reset the state to zero after a grapheme break. + */ +UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break_stateful( + utf8proc_int32_t codepoint1, utf8proc_int32_t codepoint2, utf8proc_int32_t *state); + +/** + * Same as @ref utf8proc_grapheme_break_stateful, except without support for the + * Unicode 9 additions to the algorithm. Supported for legacy reasons. + */ +UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break( + utf8proc_int32_t codepoint1, utf8proc_int32_t codepoint2); + + +/** + * Given a codepoint `c`, return the codepoint of the corresponding + * lower-case character, if any; otherwise (if there is no lower-case + * variant, or if `c` is not a valid codepoint) return `c`. + */ +UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_tolower(utf8proc_int32_t c); + +/** + * Given a codepoint `c`, return the codepoint of the corresponding + * upper-case character, if any; otherwise (if there is no upper-case + * variant, or if `c` is not a valid codepoint) return `c`. + */ +UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_toupper(utf8proc_int32_t c); + +/** + * Given a codepoint `c`, return the codepoint of the corresponding + * title-case character, if any; otherwise (if there is no title-case + * variant, or if `c` is not a valid codepoint) return `c`. + */ +UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_totitle(utf8proc_int32_t c); + +/** + * Given a codepoint `c`, return `1` if the codepoint corresponds to a lower-case character + * and `0` otherwise. + */ +UTF8PROC_DLLEXPORT int utf8proc_islower(utf8proc_int32_t c); + +/** + * Given a codepoint `c`, return `1` if the codepoint corresponds to an upper-case character + * and `0` otherwise. + */ +UTF8PROC_DLLEXPORT int utf8proc_isupper(utf8proc_int32_t c); + +/** + * Given a codepoint, return a character width analogous to `wcwidth(codepoint)`, + * except that a width of 0 is returned for non-printable codepoints + * instead of -1 as in `wcwidth`. + * + * @note + * If you want to check for particular types of non-printable characters, + * (analogous to `isprint` or `iscntrl`), use @ref utf8proc_category. */ +UTF8PROC_DLLEXPORT int utf8proc_charwidth(utf8proc_int32_t codepoint); + +/** + * Return the Unicode category for the codepoint (one of the + * @ref utf8proc_category_t constants.) + */ +UTF8PROC_DLLEXPORT utf8proc_category_t utf8proc_category(utf8proc_int32_t codepoint); + +/** + * Return the two-letter (nul-terminated) Unicode category string for + * the codepoint (e.g. `"Lu"` or `"Co"`). + */ +UTF8PROC_DLLEXPORT const char *utf8proc_category_string(utf8proc_int32_t codepoint); + +/** + * Maps the given UTF-8 string pointed to by `str` to a new UTF-8 + * string, allocated dynamically by `malloc` and returned via `dstptr`. + * + * If the @ref UTF8PROC_NULLTERM flag in the `options` field is set, + * the length is determined by a NULL terminator, otherwise the + * parameter `strlen` is evaluated to determine the string length, but + * in any case the result will be NULL terminated (though it might + * contain NULL characters with the string if `str` contained NULL + * characters). Other flags in the `options` field are passed to the + * functions defined above, and regarded as described. See also + * @ref utf8proc_map_custom to supply a custom codepoint transformation. + * + * In case of success the length of the new string is returned, + * otherwise a negative error code is returned. + * + * @note The memory of the new UTF-8 string will have been allocated + * with `malloc`, and should therefore be deallocated with `free`. + */ +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map( + const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options +); + +/** + * Like @ref utf8proc_map, but also takes a `custom_func` mapping function + * that is called on each codepoint in `str` before any other transformations + * (along with a `custom_data` pointer that is passed through to `custom_func`). + * The `custom_func` argument is ignored if it is `NULL`. + */ +UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map_custom( + const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options, + utf8proc_custom_func custom_func, void *custom_data +); + +/** @name Unicode normalization + * + * Returns a pointer to newly allocated memory of a NFD, NFC, NFKD, NFKC or + * NFKC_Casefold normalized version of the null-terminated string `str`. These + * are shortcuts to calling @ref utf8proc_map with @ref UTF8PROC_NULLTERM + * combined with @ref UTF8PROC_STABLE and flags indicating the normalization. + */ +/** @{ */ +/** NFD normalization (@ref UTF8PROC_DECOMPOSE). */ +UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFD(const utf8proc_uint8_t *str); +/** NFC normalization (@ref UTF8PROC_COMPOSE). */ +UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFC(const utf8proc_uint8_t *str); +/** NFKD normalization (@ref UTF8PROC_DECOMPOSE and @ref UTF8PROC_COMPAT). */ +UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKD(const utf8proc_uint8_t *str); +/** NFKC normalization (@ref UTF8PROC_COMPOSE and @ref UTF8PROC_COMPAT). */ +UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC(const utf8proc_uint8_t *str); +/** + * NFKC_Casefold normalization (@ref UTF8PROC_COMPOSE and @ref UTF8PROC_COMPAT + * and @ref UTF8PROC_CASEFOLD and @ref UTF8PROC_IGNORE). + **/ +UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC_Casefold(const utf8proc_uint8_t *str); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utf8proc/utf8proc_data.c b/src/utf8proc/utf8proc_data.c new file mode 100644 index 00000000..6a4ea261 --- /dev/null +++ b/src/utf8proc/utf8proc_data.c @@ -0,0 +1,16925 @@ +static const utf8proc_uint16_t utf8proc_sequences[] = { + 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 32, 32, 776, 32, 772, + 50, 51, 32, 769, 956, 32, 807, 49, + 49, 8260, 52, 49, 8260, 50, 51, 8260, + 52, 65, 768, 224, 65, 769, 225, 65, + 770, 226, 65, 771, 227, 65, 776, 228, + 65, 778, 229, 230, 67, 807, 231, 69, + 768, 232, 69, 769, 233, 69, 770, 234, + 69, 776, 235, 73, 768, 236, 73, 769, + 237, 73, 770, 238, 73, 776, 239, 240, + 78, 771, 241, 79, 768, 242, 79, 769, + 243, 79, 770, 244, 79, 771, 245, 79, + 776, 246, 248, 85, 768, 249, 85, 769, + 250, 85, 770, 251, 85, 776, 252, 89, + 769, 253, 254, 115, 115, 97, 768, 97, + 769, 97, 770, 97, 771, 97, 776, 97, + 778, 99, 807, 101, 768, 101, 769, 101, + 770, 101, 776, 105, 768, 105, 769, 105, + 770, 105, 776, 110, 771, 111, 768, 111, + 769, 111, 770, 111, 771, 111, 776, 117, + 768, 117, 769, 117, 770, 117, 776, 121, + 769, 121, 776, 65, 772, 257, 97, 772, + 65, 774, 259, 97, 774, 65, 808, 261, + 97, 808, 67, 769, 263, 99, 769, 67, + 770, 265, 99, 770, 67, 775, 267, 99, + 775, 67, 780, 269, 99, 780, 68, 780, + 271, 100, 780, 273, 69, 772, 275, 101, + 772, 69, 774, 277, 101, 774, 69, 775, + 279, 101, 775, 69, 808, 281, 101, 808, + 69, 780, 283, 101, 780, 71, 770, 285, + 103, 770, 71, 774, 287, 103, 774, 71, + 775, 289, 103, 775, 71, 807, 291, 103, + 807, 72, 770, 293, 104, 770, 295, 73, + 771, 297, 105, 771, 73, 772, 299, 105, + 772, 73, 774, 301, 105, 774, 73, 808, + 303, 105, 808, 73, 775, 105, 775, 73, + 74, 307, 105, 106, 74, 770, 309, 106, + 770, 75, 807, 311, 107, 807, 76, 769, + 314, 108, 769, 76, 807, 316, 108, 807, + 76, 780, 318, 108, 780, 76, 183, 320, + 108, 183, 322, 78, 769, 324, 110, 769, + 78, 807, 326, 110, 807, 78, 780, 328, + 110, 780, 700, 110, 331, 79, 772, 333, + 111, 772, 79, 774, 335, 111, 774, 79, + 779, 337, 111, 779, 339, 82, 769, 341, + 114, 769, 82, 807, 343, 114, 807, 82, + 780, 345, 114, 780, 83, 769, 347, 115, + 769, 83, 770, 349, 115, 770, 83, 807, + 351, 115, 807, 83, 780, 353, 115, 780, + 84, 807, 355, 116, 807, 84, 780, 357, + 116, 780, 359, 85, 771, 361, 117, 771, + 85, 772, 363, 117, 772, 85, 774, 365, + 117, 774, 85, 778, 367, 117, 778, 85, + 779, 369, 117, 779, 85, 808, 371, 117, + 808, 87, 770, 373, 119, 770, 89, 770, + 375, 121, 770, 89, 776, 255, 90, 769, + 378, 122, 769, 90, 775, 380, 122, 775, + 90, 780, 382, 122, 780, 595, 387, 389, + 596, 392, 598, 599, 396, 477, 601, 603, + 402, 608, 611, 617, 616, 409, 623, 626, + 629, 79, 795, 417, 111, 795, 419, 421, + 640, 424, 643, 429, 648, 85, 795, 432, + 117, 795, 650, 651, 436, 438, 658, 441, + 445, 68, 381, 454, 68, 382, 100, 382, + 76, 74, 457, 76, 106, 108, 106, 78, + 74, 460, 78, 106, 110, 106, 65, 780, + 462, 97, 780, 73, 780, 464, 105, 780, + 79, 780, 466, 111, 780, 85, 780, 468, + 117, 780, 220, 772, 470, 252, 772, 220, + 769, 472, 252, 769, 220, 780, 474, 252, + 780, 220, 768, 476, 252, 768, 196, 772, + 479, 228, 772, 550, 772, 481, 551, 772, + 198, 772, 483, 230, 772, 485, 71, 780, + 487, 103, 780, 75, 780, 489, 107, 780, + 79, 808, 491, 111, 808, 490, 772, 493, + 491, 772, 439, 780, 495, 658, 780, 106, + 780, 68, 90, 499, 68, 122, 100, 122, + 71, 769, 501, 103, 769, 405, 447, 78, + 768, 505, 110, 768, 197, 769, 507, 229, + 769, 198, 769, 509, 230, 769, 216, 769, + 511, 248, 769, 65, 783, 513, 97, 783, + 65, 785, 515, 97, 785, 69, 783, 517, + 101, 783, 69, 785, 519, 101, 785, 73, + 783, 521, 105, 783, 73, 785, 523, 105, + 785, 79, 783, 525, 111, 783, 79, 785, + 527, 111, 785, 82, 783, 529, 114, 783, + 82, 785, 531, 114, 785, 85, 783, 533, + 117, 783, 85, 785, 535, 117, 785, 83, + 806, 537, 115, 806, 84, 806, 539, 116, + 806, 541, 72, 780, 543, 104, 780, 414, + 547, 549, 65, 775, 551, 97, 775, 69, + 807, 553, 101, 807, 214, 772, 555, 246, + 772, 213, 772, 557, 245, 772, 79, 775, + 559, 111, 775, 558, 772, 561, 559, 772, + 89, 772, 563, 121, 772, 11365, 572, 410, + 11366, 578, 384, 649, 652, 583, 585, 587, + 589, 591, 614, 633, 635, 641, 32, 774, + 32, 775, 32, 778, 32, 808, 32, 771, + 32, 779, 661, 768, 769, 787, 776, 769, + 953, 881, 883, 697, 887, 32, 837, 59, + 1011, 168, 769, 913, 769, 940, 183, 917, + 769, 941, 919, 769, 942, 921, 769, 943, + 927, 769, 972, 933, 769, 973, 937, 769, + 974, 970, 769, 953, 776, 769, 945, 946, + 947, 948, 949, 950, 951, 952, 954, 955, + 957, 958, 959, 960, 961, 963, 964, 965, + 966, 967, 968, 969, 921, 776, 970, 933, + 776, 971, 945, 769, 949, 769, 951, 769, + 953, 769, 971, 769, 965, 776, 769, 953, + 776, 965, 776, 959, 769, 965, 769, 969, + 769, 983, 933, 978, 769, 978, 776, 985, + 987, 989, 991, 993, 995, 997, 999, 1001, + 1003, 1005, 1007, 962, 920, 1016, 931, 1010, + 1019, 891, 892, 893, 1045, 768, 1104, 1045, + 776, 1105, 1106, 1043, 769, 1107, 1108, 1109, + 1110, 1030, 776, 1111, 1112, 1113, 1114, 1115, + 1050, 769, 1116, 1048, 768, 1117, 1059, 774, + 1118, 1119, 1072, 1073, 1074, 1075, 1076, 1077, + 1078, 1079, 1080, 1048, 774, 1081, 1082, 1083, + 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, + 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1080, 774, 1077, 768, + 1077, 776, 1075, 769, 1110, 776, 1082, 769, + 1080, 768, 1091, 774, 1121, 1123, 1125, 1127, + 1129, 1131, 1133, 1135, 1137, 1139, 1141, 1140, + 783, 1143, 1141, 783, 1145, 1147, 1149, 1151, + 1153, 1163, 1165, 1167, 1169, 1171, 1173, 1175, + 1177, 1179, 1181, 1183, 1185, 1187, 1189, 1191, + 1193, 1195, 1197, 1199, 1201, 1203, 1205, 1207, + 1209, 1211, 1213, 1215, 1231, 1046, 774, 1218, + 1078, 774, 1220, 1222, 1224, 1226, 1228, 1230, + 1040, 774, 1233, 1072, 774, 1040, 776, 1235, + 1072, 776, 1237, 1045, 774, 1239, 1077, 774, + 1241, 1240, 776, 1243, 1241, 776, 1046, 776, + 1245, 1078, 776, 1047, 776, 1247, 1079, 776, + 1249, 1048, 772, 1251, 1080, 772, 1048, 776, + 1253, 1080, 776, 1054, 776, 1255, 1086, 776, + 1257, 1256, 776, 1259, 1257, 776, 1069, 776, + 1261, 1101, 776, 1059, 772, 1263, 1091, 772, + 1059, 776, 1265, 1091, 776, 1059, 779, 1267, + 1091, 779, 1063, 776, 1269, 1095, 776, 1271, + 1067, 776, 1273, 1099, 776, 1275, 1277, 1279, + 1281, 1283, 1285, 1287, 1289, 1291, 1293, 1295, + 1297, 1299, 1301, 1303, 1305, 1307, 1309, 1311, + 1313, 1315, 1317, 1319, 1321, 1323, 1325, 1327, + 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, + 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, + 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, + 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, + 1409, 1410, 1411, 1412, 1413, 1414, 1381, 1410, + 1575, 1619, 1575, 1620, 1608, 1620, 1575, 1621, + 1610, 1620, 1575, 1652, 1608, 1652, 1735, 1652, + 1610, 1652, 1749, 1620, 1729, 1620, 1746, 1620, + 2344, 2364, 2352, 2364, 2355, 2364, 2325, 2364, + 2326, 2364, 2327, 2364, 2332, 2364, 2337, 2364, + 2338, 2364, 2347, 2364, 2351, 2364, 2503, 2494, + 2503, 2519, 2465, 2492, 2466, 2492, 2479, 2492, + 2610, 2620, 2616, 2620, 2582, 2620, 2583, 2620, + 2588, 2620, 2603, 2620, 2887, 2902, 2887, 2878, + 2887, 2903, 2849, 2876, 2850, 2876, 2962, 3031, + 3014, 3006, 3015, 3006, 3014, 3031, 3142, 3158, + 3263, 3285, 3270, 3285, 3270, 3286, 3270, 3266, + 3274, 3285, 3398, 3390, 3399, 3390, 3398, 3415, + 3545, 3530, 3545, 3535, 3548, 3530, 3545, 3551, + 3661, 3634, 3789, 3762, 3755, 3737, 3755, 3745, + 3851, 3906, 4023, 3916, 4023, 3921, 4023, 3926, + 4023, 3931, 4023, 3904, 4021, 3953, 3954, 3953, + 3956, 4018, 3968, 4018, 3969, 4019, 3968, 4019, + 3969, 3953, 3968, 3986, 4023, 3996, 4023, 4001, + 4023, 4006, 4023, 4011, 4023, 3984, 4021, 4133, + 4142, 11520, 11521, 11522, 11523, 11524, 11525, 11526, + 11527, 11528, 11529, 11530, 11531, 11532, 11533, 11534, + 11535, 11536, 11537, 11538, 11539, 11540, 11541, 11542, + 11543, 11544, 11545, 11546, 11547, 11548, 11549, 11550, + 11551, 11552, 11553, 11554, 11555, 11556, 11557, 11559, + 11565, 4316, 5104, 5105, 5106, 5107, 5108, 5109, + 6917, 6965, 6919, 6965, 6921, 6965, 6923, 6965, + 6925, 6965, 6929, 6965, 6970, 6965, 6972, 6965, + 6974, 6965, 6975, 6965, 6978, 6965, 42571, 4304, + 4305, 4306, 4307, 4308, 4309, 4310, 4311, 4312, + 4313, 4314, 4315, 4317, 4318, 4319, 4320, 4321, + 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, + 4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, + 4338, 4339, 4340, 4341, 4342, 4343, 4344, 4345, + 4346, 4349, 4350, 4351, 65, 198, 66, 68, + 69, 398, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 546, 80, 82, 84, 85, + 87, 592, 593, 7426, 604, 7446, 7447, 7453, + 7461, 594, 597, 607, 609, 613, 618, 7547, + 669, 621, 7557, 671, 625, 624, 627, 628, + 632, 642, 427, 7452, 656, 657, 65, 805, + 7681, 97, 805, 66, 775, 7683, 98, 775, + 66, 803, 7685, 98, 803, 66, 817, 7687, + 98, 817, 199, 769, 7689, 231, 769, 68, + 775, 7691, 100, 775, 68, 803, 7693, 100, + 803, 68, 817, 7695, 100, 817, 68, 807, + 7697, 100, 807, 68, 813, 7699, 100, 813, + 274, 768, 7701, 275, 768, 274, 769, 7703, + 275, 769, 69, 813, 7705, 101, 813, 69, + 816, 7707, 101, 816, 552, 774, 7709, 553, + 774, 70, 775, 7711, 102, 775, 71, 772, + 7713, 103, 772, 72, 775, 7715, 104, 775, + 72, 803, 7717, 104, 803, 72, 776, 7719, + 104, 776, 72, 807, 7721, 104, 807, 72, + 814, 7723, 104, 814, 73, 816, 7725, 105, + 816, 207, 769, 7727, 239, 769, 75, 769, + 7729, 107, 769, 75, 803, 7731, 107, 803, + 75, 817, 7733, 107, 817, 76, 803, 7735, + 108, 803, 7734, 772, 7737, 7735, 772, 76, + 817, 7739, 108, 817, 76, 813, 7741, 108, + 813, 77, 769, 7743, 109, 769, 77, 775, + 7745, 109, 775, 77, 803, 7747, 109, 803, + 78, 775, 7749, 110, 775, 78, 803, 7751, + 110, 803, 78, 817, 7753, 110, 817, 78, + 813, 7755, 110, 813, 213, 769, 7757, 245, + 769, 213, 776, 7759, 245, 776, 332, 768, + 7761, 333, 768, 332, 769, 7763, 333, 769, + 80, 769, 7765, 112, 769, 80, 775, 7767, + 112, 775, 82, 775, 7769, 114, 775, 82, + 803, 7771, 114, 803, 7770, 772, 7773, 7771, + 772, 82, 817, 7775, 114, 817, 83, 775, + 7777, 115, 775, 83, 803, 7779, 115, 803, + 346, 775, 7781, 347, 775, 352, 775, 7783, + 353, 775, 7778, 775, 7785, 7779, 775, 84, + 775, 7787, 116, 775, 84, 803, 7789, 116, + 803, 84, 817, 7791, 116, 817, 84, 813, + 7793, 116, 813, 85, 804, 7795, 117, 804, + 85, 816, 7797, 117, 816, 85, 813, 7799, + 117, 813, 360, 769, 7801, 361, 769, 362, + 776, 7803, 363, 776, 86, 771, 7805, 118, + 771, 86, 803, 7807, 118, 803, 87, 768, + 7809, 119, 768, 87, 769, 7811, 119, 769, + 87, 776, 7813, 119, 776, 87, 775, 7815, + 119, 775, 87, 803, 7817, 119, 803, 88, + 775, 7819, 120, 775, 88, 776, 7821, 120, + 776, 89, 775, 7823, 121, 775, 90, 770, + 7825, 122, 770, 90, 803, 7827, 122, 803, + 90, 817, 7829, 122, 817, 104, 817, 116, + 776, 119, 778, 121, 778, 97, 702, 383, + 775, 65, 803, 7841, 97, 803, 65, 777, + 7843, 97, 777, 194, 769, 7845, 226, 769, + 194, 768, 7847, 226, 768, 194, 777, 7849, + 226, 777, 194, 771, 7851, 226, 771, 7840, + 770, 7853, 7841, 770, 258, 769, 7855, 259, + 769, 258, 768, 7857, 259, 768, 258, 777, + 7859, 259, 777, 258, 771, 7861, 259, 771, + 7840, 774, 7863, 7841, 774, 69, 803, 7865, + 101, 803, 69, 777, 7867, 101, 777, 69, + 771, 7869, 101, 771, 202, 769, 7871, 234, + 769, 202, 768, 7873, 234, 768, 202, 777, + 7875, 234, 777, 202, 771, 7877, 234, 771, + 7864, 770, 7879, 7865, 770, 73, 777, 7881, + 105, 777, 73, 803, 7883, 105, 803, 79, + 803, 7885, 111, 803, 79, 777, 7887, 111, + 777, 212, 769, 7889, 244, 769, 212, 768, + 7891, 244, 768, 212, 777, 7893, 244, 777, + 212, 771, 7895, 244, 771, 7884, 770, 7897, + 7885, 770, 416, 769, 7899, 417, 769, 416, + 768, 7901, 417, 768, 416, 777, 7903, 417, + 777, 416, 771, 7905, 417, 771, 416, 803, + 7907, 417, 803, 85, 803, 7909, 117, 803, + 85, 777, 7911, 117, 777, 431, 769, 7913, + 432, 769, 431, 768, 7915, 432, 768, 431, + 777, 7917, 432, 777, 431, 771, 7919, 432, + 771, 431, 803, 7921, 432, 803, 89, 768, + 7923, 121, 768, 89, 803, 7925, 121, 803, + 89, 777, 7927, 121, 777, 89, 771, 7929, + 121, 771, 7931, 7933, 7935, 945, 787, 945, + 788, 7936, 768, 7937, 768, 7936, 769, 7937, + 769, 7936, 834, 7937, 834, 913, 787, 7936, + 913, 788, 7937, 7944, 768, 7938, 7945, 768, + 7939, 7944, 769, 7940, 7945, 769, 7941, 7944, + 834, 7942, 7945, 834, 7943, 949, 787, 949, + 788, 7952, 768, 7953, 768, 7952, 769, 7953, + 769, 917, 787, 7952, 917, 788, 7953, 7960, + 768, 7954, 7961, 768, 7955, 7960, 769, 7956, + 7961, 769, 7957, 951, 787, 951, 788, 7968, + 768, 7969, 768, 7968, 769, 7969, 769, 7968, + 834, 7969, 834, 919, 787, 7968, 919, 788, + 7969, 7976, 768, 7970, 7977, 768, 7971, 7976, + 769, 7972, 7977, 769, 7973, 7976, 834, 7974, + 7977, 834, 7975, 953, 787, 953, 788, 7984, + 768, 7985, 768, 7984, 769, 7985, 769, 7984, + 834, 7985, 834, 921, 787, 7984, 921, 788, + 7985, 7992, 768, 7986, 7993, 768, 7987, 7992, + 769, 7988, 7993, 769, 7989, 7992, 834, 7990, + 7993, 834, 7991, 959, 787, 959, 788, 8000, + 768, 8001, 768, 8000, 769, 8001, 769, 927, + 787, 8000, 927, 788, 8001, 8008, 768, 8002, + 8009, 768, 8003, 8008, 769, 8004, 8009, 769, + 8005, 965, 787, 965, 788, 8016, 768, 965, + 787, 768, 8017, 768, 8016, 769, 965, 787, + 769, 8017, 769, 8016, 834, 965, 787, 834, + 8017, 834, 933, 788, 8017, 8025, 768, 8019, + 8025, 769, 8021, 8025, 834, 8023, 969, 787, + 969, 788, 8032, 768, 8033, 768, 8032, 769, + 8033, 769, 8032, 834, 8033, 834, 937, 787, + 8032, 937, 788, 8033, 8040, 768, 8034, 8041, + 768, 8035, 8040, 769, 8036, 8041, 769, 8037, + 8040, 834, 8038, 8041, 834, 8039, 945, 768, + 949, 768, 951, 768, 953, 768, 959, 768, + 965, 768, 969, 768, 7936, 837, 7936, 953, + 7937, 837, 7937, 953, 7938, 837, 7938, 953, + 7939, 837, 7939, 953, 7940, 837, 7940, 953, + 7941, 837, 7941, 953, 7942, 837, 7942, 953, + 7943, 837, 7943, 953, 7944, 837, 7945, 837, + 7946, 837, 7947, 837, 7948, 837, 7949, 837, + 7950, 837, 7951, 837, 7968, 837, 7968, 953, + 7969, 837, 7969, 953, 7970, 837, 7970, 953, + 7971, 837, 7971, 953, 7972, 837, 7972, 953, + 7973, 837, 7973, 953, 7974, 837, 7974, 953, + 7975, 837, 7975, 953, 7976, 837, 7977, 837, + 7978, 837, 7979, 837, 7980, 837, 7981, 837, + 7982, 837, 7983, 837, 8032, 837, 8032, 953, + 8033, 837, 8033, 953, 8034, 837, 8034, 953, + 8035, 837, 8035, 953, 8036, 837, 8036, 953, + 8037, 837, 8037, 953, 8038, 837, 8038, 953, + 8039, 837, 8039, 953, 8040, 837, 8041, 837, + 8042, 837, 8043, 837, 8044, 837, 8045, 837, + 8046, 837, 8047, 837, 945, 774, 945, 772, + 8048, 837, 8048, 953, 945, 837, 945, 953, + 940, 837, 940, 953, 945, 834, 8118, 837, + 945, 834, 953, 913, 774, 8112, 913, 772, + 8113, 913, 768, 8048, 902, 8049, 913, 837, + 32, 787, 32, 834, 168, 834, 8052, 837, + 8052, 953, 951, 837, 951, 953, 942, 837, + 942, 953, 951, 834, 8134, 837, 951, 834, + 953, 917, 768, 8050, 904, 8051, 919, 768, + 8052, 905, 8053, 919, 837, 8127, 768, 8127, + 769, 8127, 834, 953, 774, 953, 772, 970, + 768, 953, 776, 768, 912, 953, 834, 970, + 834, 953, 776, 834, 921, 774, 8144, 921, + 772, 8145, 921, 768, 8054, 906, 8055, 8190, + 768, 8190, 769, 8190, 834, 965, 774, 965, + 772, 971, 768, 965, 776, 768, 944, 961, + 787, 961, 788, 965, 834, 971, 834, 965, + 776, 834, 933, 774, 8160, 933, 772, 8161, + 933, 768, 8058, 910, 8059, 929, 788, 8165, + 168, 768, 901, 96, 8060, 837, 8060, 953, + 969, 837, 969, 953, 974, 837, 974, 953, + 969, 834, 8182, 837, 969, 834, 953, 927, + 768, 8056, 908, 8057, 937, 768, 8060, 911, + 8061, 937, 837, 180, 32, 788, 8194, 8195, + 8208, 32, 819, 46, 46, 46, 46, 46, + 46, 8242, 8242, 8242, 8242, 8242, 8245, 8245, + 8245, 8245, 8245, 33, 33, 32, 773, 63, + 63, 63, 33, 33, 63, 3, 8242, 8242, + 8242, 8242, 48, 52, 53, 54, 55, 56, + 57, 43, 8722, 61, 40, 41, 82, 115, + 97, 47, 99, 97, 47, 115, 67, 176, + 67, 99, 47, 111, 99, 47, 117, 400, + 176, 70, 78, 111, 81, 83, 77, 84, + 69, 76, 84, 77, 90, 937, 197, 70, + 8526, 1488, 1489, 1490, 1491, 70, 65, 88, + 915, 928, 8721, 49, 8260, 55, 49, 8260, + 57, 3, 49, 8260, 49, 48, 49, 8260, + 51, 50, 8260, 51, 49, 8260, 53, 50, + 8260, 53, 51, 8260, 53, 52, 8260, 53, + 49, 8260, 54, 53, 8260, 54, 49, 8260, + 56, 51, 8260, 56, 53, 8260, 56, 55, + 8260, 56, 49, 8260, 8560, 73, 73, 8561, + 73, 73, 73, 8562, 73, 86, 8563, 86, + 8564, 86, 73, 8565, 86, 73, 73, 8566, + 3, 86, 73, 73, 73, 8567, 73, 88, + 8568, 88, 8569, 88, 73, 8570, 88, 73, + 73, 8571, 8572, 8573, 8574, 8575, 105, 105, + 105, 105, 105, 105, 118, 118, 105, 118, + 105, 105, 3, 118, 105, 105, 105, 105, + 120, 120, 105, 120, 105, 105, 8580, 48, + 8260, 51, 8592, 824, 8594, 824, 8596, 824, + 8656, 824, 8660, 824, 8658, 824, 8707, 824, + 8712, 824, 8715, 824, 8739, 824, 8741, 824, + 8747, 8747, 8747, 8747, 8747, 8750, 8750, 8750, + 8750, 8750, 8764, 824, 8771, 824, 8773, 824, + 8776, 824, 61, 824, 8801, 824, 8781, 824, + 60, 824, 62, 824, 8804, 824, 8805, 824, + 8818, 824, 8819, 824, 8822, 824, 8823, 824, + 8826, 824, 8827, 824, 8834, 824, 8835, 824, + 8838, 824, 8839, 824, 8866, 824, 8872, 824, + 8873, 824, 8875, 824, 8828, 824, 8829, 824, + 8849, 824, 8850, 824, 8882, 824, 8883, 824, + 8884, 824, 8885, 824, 12296, 12297, 49, 48, + 49, 49, 49, 50, 49, 51, 49, 52, + 49, 53, 49, 54, 49, 55, 49, 56, + 49, 57, 50, 48, 40, 49, 41, 40, + 50, 41, 40, 51, 41, 40, 52, 41, + 40, 53, 41, 40, 54, 41, 40, 55, + 41, 40, 56, 41, 40, 57, 41, 3, + 40, 49, 48, 41, 3, 40, 49, 49, + 41, 3, 40, 49, 50, 41, 3, 40, + 49, 51, 41, 3, 40, 49, 52, 41, + 3, 40, 49, 53, 41, 3, 40, 49, + 54, 41, 3, 40, 49, 55, 41, 3, + 40, 49, 56, 41, 3, 40, 49, 57, + 41, 3, 40, 50, 48, 41, 49, 46, + 50, 46, 51, 46, 52, 46, 53, 46, + 54, 46, 55, 46, 56, 46, 57, 46, + 49, 48, 46, 49, 49, 46, 49, 50, + 46, 49, 51, 46, 49, 52, 46, 49, + 53, 46, 49, 54, 46, 49, 55, 46, + 49, 56, 46, 49, 57, 46, 50, 48, + 46, 40, 97, 41, 40, 98, 41, 40, + 99, 41, 40, 100, 41, 40, 101, 41, + 40, 102, 41, 40, 103, 41, 40, 104, + 41, 40, 105, 41, 40, 106, 41, 40, + 107, 41, 40, 108, 41, 40, 109, 41, + 40, 110, 41, 40, 111, 41, 40, 112, + 41, 40, 113, 41, 40, 114, 41, 40, + 115, 41, 40, 116, 41, 40, 117, 41, + 40, 118, 41, 40, 119, 41, 40, 120, + 41, 40, 121, 41, 40, 122, 41, 9424, + 9425, 9426, 9427, 9428, 9429, 9430, 9431, 9432, + 9433, 9434, 9435, 9436, 9437, 9438, 9439, 9440, + 9441, 83, 9442, 9443, 9444, 9445, 9446, 9447, + 89, 9448, 9449, 3, 8747, 8747, 8747, 8747, + 58, 58, 61, 61, 61, 61, 61, 61, + 10973, 824, 11312, 11313, 11314, 11315, 11316, 11317, + 11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, + 11326, 11327, 11328, 11329, 11330, 11331, 11332, 11333, + 11334, 11335, 11336, 11337, 11338, 11339, 11340, 11341, + 11342, 11343, 11344, 11345, 11346, 11347, 11348, 11349, + 11350, 11351, 11352, 11353, 11354, 11355, 11356, 11357, + 11358, 11359, 11361, 619, 7549, 637, 11368, 11370, + 11372, 11379, 11382, 575, 576, 11393, 11395, 11397, + 11399, 11401, 11403, 11405, 11407, 11409, 11411, 11413, + 11415, 11417, 11419, 11421, 11423, 11425, 11427, 11429, + 11431, 11433, 11435, 11437, 11439, 11441, 11443, 11445, + 11447, 11449, 11451, 11453, 11455, 11457, 11459, 11461, + 11463, 11465, 11467, 11469, 11471, 11473, 11475, 11477, + 11479, 11481, 11483, 11485, 11487, 11489, 11491, 11500, + 11502, 11507, 11617, 27597, 40863, 19968, 20008, 20022, + 20031, 20057, 20101, 20108, 20128, 20154, 20799, 20837, + 20843, 20866, 20886, 20907, 20960, 20981, 20992, 21147, + 21241, 21269, 21274, 21304, 21313, 21340, 21353, 21378, + 21430, 21448, 21475, 22231, 22303, 22763, 22786, 22794, + 22805, 22823, 22899, 23376, 23424, 23544, 23567, 23586, + 23608, 23662, 23665, 24027, 24037, 24049, 24062, 24178, + 24186, 24191, 24308, 24318, 24331, 24339, 24400, 24417, + 24435, 24515, 25096, 25142, 25163, 25903, 25908, 25991, + 26007, 26020, 26041, 26080, 26085, 26352, 26376, 26408, + 27424, 27490, 27513, 27571, 27595, 27604, 27611, 27663, + 27668, 27700, 28779, 29226, 29238, 29243, 29247, 29255, + 29273, 29275, 29356, 29572, 29577, 29916, 29926, 29976, + 29983, 29992, 30000, 30091, 30098, 30326, 30333, 30382, + 30399, 30446, 30683, 30690, 30707, 31034, 31160, 31166, + 31348, 31435, 31481, 31859, 31992, 32566, 32593, 32650, + 32701, 32769, 32780, 32786, 32819, 32895, 32905, 33251, + 33258, 33267, 33276, 33292, 33307, 33311, 33390, 33394, + 33400, 34381, 34411, 34880, 34892, 34915, 35198, 35211, + 35282, 35328, 35895, 35910, 35925, 35960, 35997, 36196, + 36208, 36275, 36523, 36554, 36763, 36784, 36789, 37009, + 37193, 37318, 37324, 37329, 38263, 38272, 38428, 38582, + 38585, 38632, 38737, 38750, 38754, 38761, 38859, 38893, + 38899, 38913, 39080, 39131, 39135, 39318, 39321, 39340, + 39592, 39640, 39647, 39717, 39727, 39730, 39740, 39770, + 40165, 40565, 40575, 40613, 40635, 40643, 40653, 40657, + 40697, 40701, 40718, 40723, 40736, 40763, 40778, 40786, + 40845, 40860, 40864, 12306, 21316, 21317, 12363, 12441, + 12365, 12441, 12367, 12441, 12369, 12441, 12371, 12441, + 12373, 12441, 12375, 12441, 12377, 12441, 12379, 12441, + 12381, 12441, 12383, 12441, 12385, 12441, 12388, 12441, + 12390, 12441, 12392, 12441, 12399, 12441, 12399, 12442, + 12402, 12441, 12402, 12442, 12405, 12441, 12405, 12442, + 12408, 12441, 12408, 12442, 12411, 12441, 12411, 12442, + 12358, 12441, 32, 12441, 32, 12442, 12445, 12441, + 12424, 12426, 12459, 12441, 12461, 12441, 12463, 12441, + 12465, 12441, 12467, 12441, 12469, 12441, 12471, 12441, + 12473, 12441, 12475, 12441, 12477, 12441, 12479, 12441, + 12481, 12441, 12484, 12441, 12486, 12441, 12488, 12441, + 12495, 12441, 12495, 12442, 12498, 12441, 12498, 12442, + 12501, 12441, 12501, 12442, 12504, 12441, 12504, 12442, + 12507, 12441, 12507, 12442, 12454, 12441, 12527, 12441, + 12528, 12441, 12529, 12441, 12530, 12441, 12541, 12441, + 12467, 12488, 4352, 4353, 4522, 4354, 4524, 4525, + 4355, 4356, 4357, 4528, 4529, 4530, 4531, 4532, + 4533, 4378, 4358, 4359, 4360, 4385, 4361, 4362, + 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, + 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, + 4457, 4458, 4459, 4460, 4461, 4462, 4463, 4464, + 4465, 4466, 4467, 4468, 4469, 4448, 4372, 4373, + 4551, 4552, 4556, 4558, 4563, 4567, 4569, 4380, + 4573, 4575, 4381, 4382, 4384, 4386, 4387, 4391, + 4393, 4395, 4396, 4397, 4398, 4399, 4402, 4406, + 4416, 4423, 4428, 4593, 4594, 4439, 4440, 4441, + 4484, 4485, 4488, 4497, 4498, 4500, 4510, 4513, + 19977, 22235, 19978, 20013, 19979, 30002, 19993, 19969, + 22825, 22320, 40, 4352, 41, 40, 4354, 41, + 40, 4355, 41, 40, 4357, 41, 40, 4358, + 41, 40, 4359, 41, 40, 4361, 41, 40, + 4363, 41, 40, 4364, 41, 40, 4366, 41, + 40, 4367, 41, 40, 4368, 41, 40, 4369, + 41, 40, 4370, 41, 3, 40, 4352, 4449, + 41, 3, 40, 4354, 4449, 41, 3, 40, + 4355, 4449, 41, 3, 40, 4357, 4449, 41, + 3, 40, 4358, 4449, 41, 3, 40, 4359, + 4449, 41, 3, 40, 4361, 4449, 41, 3, + 40, 4363, 4449, 41, 3, 40, 4364, 4449, + 41, 3, 40, 4366, 4449, 41, 3, 40, + 4367, 4449, 41, 3, 40, 4368, 4449, 41, + 3, 40, 4369, 4449, 41, 3, 40, 4370, + 4449, 41, 3, 40, 4364, 4462, 41, 6, + 40, 4363, 4457, 4364, 4453, 4523, 41, 5, + 40, 4363, 4457, 4370, 4462, 41, 40, 19968, + 41, 40, 20108, 41, 40, 19977, 41, 40, + 22235, 41, 40, 20116, 41, 40, 20845, 41, + 40, 19971, 41, 40, 20843, 41, 40, 20061, + 41, 40, 21313, 41, 40, 26376, 41, 40, + 28779, 41, 40, 27700, 41, 40, 26408, 41, + 40, 37329, 41, 40, 22303, 41, 40, 26085, + 41, 40, 26666, 41, 40, 26377, 41, 40, + 31038, 41, 40, 21517, 41, 40, 29305, 41, + 40, 36001, 41, 40, 31069, 41, 40, 21172, + 41, 40, 20195, 41, 40, 21628, 41, 40, + 23398, 41, 40, 30435, 41, 40, 20225, 41, + 40, 36039, 41, 40, 21332, 41, 40, 31085, + 41, 40, 20241, 41, 40, 33258, 41, 40, + 33267, 41, 21839, 24188, 31631, 80, 84, 69, + 50, 49, 50, 50, 50, 51, 50, 52, + 50, 53, 50, 54, 50, 55, 50, 56, + 50, 57, 51, 48, 51, 49, 51, 50, + 51, 51, 51, 52, 51, 53, 4352, 4449, + 4354, 4449, 4355, 4449, 4357, 4449, 4358, 4449, + 4359, 4449, 4361, 4449, 4363, 4449, 4364, 4449, + 4366, 4449, 4367, 4449, 4368, 4449, 4369, 4449, + 4370, 4449, 4, 4366, 4449, 4535, 4352, 4457, + 3, 4364, 4462, 4363, 4468, 4363, 4462, 20116, + 20845, 19971, 20061, 26666, 26377, 31038, 21517, 29305, + 36001, 31069, 21172, 31192, 30007, 36969, 20778, 21360, + 27880, 38917, 20241, 20889, 27491, 24038, 21491, 21307, + 23447, 23398, 30435, 20225, 36039, 21332, 22812, 51, + 54, 51, 55, 51, 56, 51, 57, 52, + 48, 52, 49, 52, 50, 52, 51, 52, + 52, 52, 53, 52, 54, 52, 55, 52, + 56, 52, 57, 53, 48, 49, 26376, 50, + 26376, 51, 26376, 52, 26376, 53, 26376, 54, + 26376, 55, 26376, 56, 26376, 57, 26376, 49, + 48, 26376, 49, 49, 26376, 49, 50, 26376, + 72, 103, 101, 114, 103, 101, 86, 76, + 84, 68, 12450, 12452, 12454, 12456, 12458, 12459, + 12461, 12463, 12465, 12467, 12469, 12471, 12473, 12475, + 12477, 12479, 12481, 12484, 12486, 12488, 12490, 12491, + 12492, 12493, 12494, 12495, 12498, 12501, 12504, 12507, + 12510, 12511, 12512, 12513, 12514, 12516, 12518, 12520, + 12521, 12522, 12523, 12524, 12525, 12527, 12528, 12529, + 12530, 20196, 21644, 3, 12450, 12497, 12540, 12488, + 3, 12450, 12523, 12501, 12449, 3, 12450, 12531, + 12506, 12450, 12450, 12540, 12523, 3, 12452, 12491, + 12531, 12464, 12452, 12531, 12481, 12454, 12457, 12531, + 4, 12456, 12473, 12463, 12540, 12489, 3, 12456, + 12540, 12459, 12540, 12458, 12531, 12473, 12458, 12540, + 12512, 12459, 12452, 12522, 3, 12459, 12521, 12483, + 12488, 3, 12459, 12525, 12522, 12540, 12460, 12525, + 12531, 12460, 12531, 12510, 12462, 12460, 12462, 12491, + 12540, 3, 12461, 12517, 12522, 12540, 3, 12462, + 12523, 12480, 12540, 12461, 12525, 4, 12461, 12525, + 12464, 12521, 12512, 5, 12461, 12525, 12513, 12540, + 12488, 12523, 4, 12461, 12525, 12527, 12483, 12488, + 12464, 12521, 12512, 4, 12464, 12521, 12512, 12488, + 12531, 4, 12463, 12523, 12476, 12452, 12525, 3, + 12463, 12525, 12540, 12493, 12465, 12540, 12473, 12467, + 12523, 12490, 12467, 12540, 12509, 3, 12469, 12452, + 12463, 12523, 4, 12469, 12531, 12481, 12540, 12512, + 3, 12471, 12522, 12531, 12464, 12475, 12531, 12481, + 12475, 12531, 12488, 12480, 12540, 12473, 12487, 12471, + 12489, 12523, 12488, 12531, 12490, 12494, 12494, 12483, + 12488, 12495, 12452, 12484, 4, 12497, 12540, 12475, + 12531, 12488, 12497, 12540, 12484, 3, 12496, 12540, + 12524, 12523, 4, 12500, 12450, 12473, 12488, 12523, + 12500, 12463, 12523, 12500, 12467, 12499, 12523, 4, + 12501, 12449, 12521, 12483, 12489, 3, 12501, 12451, + 12540, 12488, 4, 12502, 12483, 12471, 12455, 12523, + 12501, 12521, 12531, 4, 12504, 12463, 12479, 12540, + 12523, 12506, 12477, 12506, 12491, 12498, 12504, 12523, + 12484, 12506, 12531, 12473, 12506, 12540, 12472, 12505, + 12540, 12479, 3, 12509, 12452, 12531, 12488, 12508, + 12523, 12488, 12507, 12531, 12509, 12531, 12489, 12507, + 12540, 12523, 12507, 12540, 12531, 3, 12510, 12452, + 12463, 12525, 12510, 12452, 12523, 12510, 12483, 12495, + 12510, 12523, 12463, 4, 12510, 12531, 12471, 12519, + 12531, 3, 12511, 12463, 12525, 12531, 12511, 12522, + 4, 12511, 12522, 12496, 12540, 12523, 12513, 12460, + 3, 12513, 12460, 12488, 12531, 3, 12513, 12540, + 12488, 12523, 12516, 12540, 12489, 12516, 12540, 12523, + 12518, 12450, 12531, 3, 12522, 12483, 12488, 12523, + 12522, 12521, 12523, 12500, 12540, 3, 12523, 12540, + 12502, 12523, 12524, 12512, 4, 12524, 12531, 12488, + 12466, 12531, 12527, 12483, 12488, 48, 28857, 49, + 28857, 50, 28857, 51, 28857, 52, 28857, 53, + 28857, 54, 28857, 55, 28857, 56, 28857, 57, + 28857, 49, 48, 28857, 49, 49, 28857, 49, + 50, 28857, 49, 51, 28857, 49, 52, 28857, + 49, 53, 28857, 49, 54, 28857, 49, 55, + 28857, 49, 56, 28857, 49, 57, 28857, 50, + 48, 28857, 50, 49, 28857, 50, 50, 28857, + 50, 51, 28857, 50, 52, 28857, 104, 80, + 97, 100, 97, 65, 85, 98, 97, 114, + 111, 86, 112, 99, 100, 109, 100, 109, + 178, 100, 109, 179, 73, 85, 24179, 25104, + 26157, 21644, 22823, 27491, 26126, 27835, 3, 26666, + 24335, 20250, 31038, 112, 65, 110, 65, 956, + 65, 109, 65, 107, 65, 75, 66, 77, + 66, 71, 66, 99, 97, 108, 3, 107, + 99, 97, 108, 112, 70, 110, 70, 956, + 70, 956, 103, 109, 103, 107, 103, 72, + 122, 107, 72, 122, 77, 72, 122, 71, + 72, 122, 84, 72, 122, 956, 8467, 109, + 8467, 100, 8467, 107, 8467, 102, 109, 110, + 109, 956, 109, 109, 109, 99, 109, 107, + 109, 109, 109, 178, 99, 109, 178, 109, + 178, 107, 109, 178, 109, 109, 179, 99, + 109, 179, 109, 179, 107, 109, 179, 109, + 8725, 115, 3, 109, 8725, 115, 178, 80, + 97, 107, 80, 97, 77, 80, 97, 71, + 80, 97, 114, 97, 100, 4, 114, 97, + 100, 8725, 115, 5, 114, 97, 100, 8725, + 115, 178, 112, 115, 110, 115, 956, 115, + 109, 115, 112, 86, 110, 86, 956, 86, + 109, 86, 107, 86, 77, 86, 112, 87, + 110, 87, 956, 87, 109, 87, 107, 87, + 77, 87, 107, 937, 77, 937, 3, 97, + 46, 109, 46, 66, 113, 99, 99, 99, + 100, 3, 67, 8725, 107, 103, 67, 111, + 46, 100, 66, 71, 121, 104, 97, 72, + 80, 105, 110, 75, 75, 75, 77, 107, + 116, 108, 109, 108, 110, 108, 111, 103, + 108, 120, 109, 98, 109, 105, 108, 109, + 111, 108, 80, 72, 3, 112, 46, 109, + 46, 80, 80, 77, 80, 82, 115, 114, + 83, 118, 87, 98, 86, 8725, 109, 65, + 8725, 109, 49, 26085, 50, 26085, 51, 26085, + 52, 26085, 53, 26085, 54, 26085, 55, 26085, + 56, 26085, 57, 26085, 49, 48, 26085, 49, + 49, 26085, 49, 50, 26085, 49, 51, 26085, + 49, 52, 26085, 49, 53, 26085, 49, 54, + 26085, 49, 55, 26085, 49, 56, 26085, 49, + 57, 26085, 50, 48, 26085, 50, 49, 26085, + 50, 50, 26085, 50, 51, 26085, 50, 52, + 26085, 50, 53, 26085, 50, 54, 26085, 50, + 55, 26085, 50, 56, 26085, 50, 57, 26085, + 51, 48, 26085, 51, 49, 26085, 103, 97, + 108, 42561, 42563, 42565, 42567, 42569, 42573, 42575, + 42577, 42579, 42581, 42583, 42585, 42587, 42589, 42591, + 42593, 42595, 42597, 42599, 42601, 42603, 42605, 42625, + 42627, 42629, 42631, 42633, 42635, 42637, 42639, 42641, + 42643, 42645, 42647, 42649, 42651, 42787, 42789, 42791, + 42793, 42795, 42797, 42799, 42803, 42805, 42807, 42809, + 42811, 42813, 42815, 42817, 42819, 42821, 42823, 42825, + 42827, 42829, 42831, 42833, 42835, 42837, 42839, 42841, + 42843, 42845, 42847, 42849, 42851, 42853, 42855, 42857, + 42859, 42861, 42863, 42874, 42876, 7545, 42879, 42881, + 42883, 42885, 42887, 42892, 42897, 42899, 42903, 42905, + 42907, 42909, 42911, 42913, 42915, 42917, 42919, 42921, + 620, 670, 647, 43859, 42933, 42935, 42937, 42939, + 42941, 42943, 42945, 42947, 42900, 7566, 42952, 42954, + 42961, 42967, 42969, 42998, 294, 43831, 43858, 653, + 5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, + 5032, 5033, 5034, 5035, 5036, 5037, 5038, 5039, + 5040, 5041, 5042, 5043, 5044, 5045, 5046, 5047, + 5048, 5049, 5050, 5051, 5052, 5053, 5054, 5055, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 5074, 5075, 5076, 5077, 5078, 5079, + 5080, 5081, 5082, 5083, 5084, 5085, 5086, 5087, + 5088, 5089, 5090, 5091, 5092, 5093, 5094, 5095, + 5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103, + 35912, 26356, 36040, 28369, 20018, 21477, 22865, 21895, + 22856, 25078, 30313, 32645, 34367, 34746, 35064, 37007, + 27138, 27931, 28889, 29662, 33853, 37226, 39409, 20098, + 21365, 27396, 29211, 34349, 40478, 23888, 28651, 34253, + 35172, 25289, 33240, 34847, 24266, 26391, 28010, 29436, + 37070, 20358, 20919, 21214, 25796, 27347, 29200, 30439, + 34310, 34396, 36335, 38706, 39791, 40442, 30860, 31103, + 32160, 33737, 37636, 35542, 22751, 24324, 31840, 32894, + 29282, 30922, 36034, 38647, 22744, 23650, 27155, 28122, + 28431, 32047, 32311, 38475, 21202, 32907, 20956, 20940, + 31260, 32190, 33777, 38517, 35712, 25295, 35582, 20025, + 23527, 24594, 29575, 30064, 21271, 30971, 20415, 24489, + 19981, 27852, 25976, 32034, 21443, 22622, 30465, 33865, + 35498, 27578, 27784, 25342, 33509, 25504, 30053, 20142, + 20841, 20937, 26753, 31975, 33391, 35538, 37327, 21237, + 21570, 24300, 26053, 28670, 31018, 38317, 39530, 40599, + 40654, 26310, 27511, 36706, 24180, 24976, 25088, 25754, + 28451, 29001, 29833, 31178, 32244, 32879, 36646, 34030, + 36899, 37706, 21015, 21155, 21693, 28872, 35010, 24265, + 24565, 25467, 27566, 31806, 29557, 20196, 22265, 23994, + 24604, 29618, 29801, 32666, 32838, 37428, 38646, 38728, + 38936, 20363, 31150, 37300, 38584, 24801, 20102, 20698, + 23534, 23615, 26009, 29134, 30274, 34044, 36988, 26248, + 38446, 21129, 26491, 26611, 27969, 28316, 29705, 30041, + 30827, 32016, 39006, 25134, 38520, 20523, 23833, 28138, + 36650, 24459, 24900, 26647, 38534, 21033, 21519, 23653, + 26131, 26446, 26792, 27877, 29702, 30178, 32633, 35023, + 35041, 38626, 21311, 28346, 21533, 29136, 29848, 34298, + 38563, 40023, 40607, 26519, 28107, 33256, 31520, 31890, + 29376, 28825, 35672, 20160, 33590, 21050, 20999, 24230, + 25299, 31958, 23429, 27934, 26292, 36667, 38477, 24275, + 20800, 21952, 22618, 26228, 20958, 29482, 30410, 31036, + 31070, 31077, 31119, 38742, 31934, 34322, 35576, 36920, + 37117, 39151, 39164, 39208, 40372, 37086, 38583, 20398, + 20711, 20813, 21193, 21220, 21329, 21917, 22022, 22120, + 22592, 22696, 23652, 24724, 24936, 24974, 25074, 25935, + 26082, 26257, 26757, 28023, 28186, 28450, 29038, 29227, + 29730, 30865, 31049, 31048, 31056, 31062, 31117, 31118, + 31296, 31361, 31680, 32265, 32321, 32626, 32773, 33261, + 33401, 33879, 35088, 35222, 35585, 35641, 36051, 36104, + 36790, 38627, 38911, 38971, 24693, 55376, 57070, 33304, + 20006, 20917, 20840, 20352, 20805, 20864, 21191, 21242, + 21845, 21913, 21986, 22707, 22852, 22868, 23138, 23336, + 24274, 24281, 24425, 24493, 24792, 24910, 24840, 24928, + 25140, 25540, 25628, 25682, 25942, 26395, 26454, 28379, + 28363, 28702, 30631, 29237, 29359, 29809, 29958, 30011, + 30237, 30239, 30427, 30452, 30538, 30528, 30924, 31409, + 31867, 32091, 32574, 33618, 33775, 34681, 35137, 35206, + 35519, 35531, 35565, 35722, 36664, 36978, 37273, 37494, + 38524, 38875, 38923, 39698, 55370, 56394, 55370, 56388, + 55372, 57301, 15261, 16408, 16441, 55380, 56905, 55383, + 56528, 55391, 57043, 40771, 40846, 102, 102, 102, + 105, 102, 108, 102, 102, 105, 102, 102, + 108, 383, 116, 115, 116, 1396, 1398, 1396, + 1381, 1396, 1387, 1406, 1398, 1396, 1389, 1497, + 1460, 1522, 1463, 1506, 1492, 1499, 1500, 1501, + 1512, 1514, 1513, 1473, 1513, 1474, 64329, 1473, + 64329, 1474, 1488, 1463, 1488, 1464, 1488, 1468, + 1489, 1468, 1490, 1468, 1491, 1468, 1492, 1468, + 1493, 1468, 1494, 1468, 1496, 1468, 1497, 1468, + 1498, 1468, 1499, 1468, 1500, 1468, 1502, 1468, + 1504, 1468, 1505, 1468, 1507, 1468, 1508, 1468, + 1510, 1468, 1511, 1468, 1512, 1468, 1513, 1468, + 1514, 1468, 1493, 1465, 1489, 1471, 1499, 1471, + 1508, 1471, 1488, 1500, 1649, 1659, 1662, 1664, + 1658, 1663, 1657, 1700, 1702, 1668, 1667, 1670, + 1671, 1677, 1676, 1678, 1672, 1688, 1681, 1705, + 1711, 1715, 1713, 1722, 1723, 1728, 1729, 1726, + 1746, 1747, 1709, 1735, 1734, 1736, 1655, 1739, + 1733, 1737, 1744, 1609, 1574, 1575, 1574, 1749, + 1574, 1608, 1574, 1735, 1574, 1734, 1574, 1736, + 1574, 1744, 1574, 1609, 1740, 1574, 1580, 1574, + 1581, 1574, 1605, 1574, 1610, 1576, 1580, 1576, + 1581, 1576, 1582, 1576, 1605, 1576, 1609, 1576, + 1610, 1578, 1580, 1578, 1581, 1578, 1582, 1578, + 1605, 1578, 1609, 1578, 1610, 1579, 1580, 1579, + 1605, 1579, 1609, 1579, 1610, 1580, 1581, 1580, + 1605, 1581, 1580, 1581, 1605, 1582, 1580, 1582, + 1581, 1582, 1605, 1587, 1580, 1587, 1581, 1587, + 1582, 1587, 1605, 1589, 1581, 1589, 1605, 1590, + 1580, 1590, 1581, 1590, 1582, 1590, 1605, 1591, + 1581, 1591, 1605, 1592, 1605, 1593, 1580, 1593, + 1605, 1594, 1580, 1594, 1605, 1601, 1580, 1601, + 1581, 1601, 1582, 1601, 1605, 1601, 1609, 1601, + 1610, 1602, 1581, 1602, 1605, 1602, 1609, 1602, + 1610, 1603, 1575, 1603, 1580, 1603, 1581, 1603, + 1582, 1603, 1604, 1603, 1605, 1603, 1609, 1603, + 1610, 1604, 1580, 1604, 1581, 1604, 1582, 1604, + 1605, 1604, 1609, 1604, 1610, 1605, 1580, 1605, + 1581, 1605, 1582, 1605, 1605, 1605, 1609, 1605, + 1610, 1606, 1580, 1606, 1581, 1606, 1582, 1606, + 1605, 1606, 1609, 1606, 1610, 1607, 1580, 1607, + 1605, 1607, 1609, 1607, 1610, 1610, 1580, 1610, + 1581, 1610, 1582, 1610, 1605, 1610, 1609, 1610, + 1610, 1584, 1648, 1585, 1648, 1609, 1648, 32, + 1612, 1617, 32, 1613, 1617, 32, 1614, 1617, + 32, 1615, 1617, 32, 1616, 1617, 32, 1617, + 1648, 1574, 1585, 1574, 1586, 1574, 1606, 1576, + 1585, 1576, 1586, 1576, 1606, 1578, 1585, 1578, + 1586, 1578, 1606, 1579, 1585, 1579, 1586, 1579, + 1606, 1605, 1575, 1606, 1585, 1606, 1586, 1606, + 1606, 1610, 1585, 1610, 1586, 1610, 1606, 1574, + 1582, 1574, 1607, 1576, 1607, 1578, 1607, 1589, + 1582, 1604, 1607, 1606, 1607, 1607, 1648, 1610, + 1607, 1579, 1607, 1587, 1607, 1588, 1605, 1588, + 1607, 1600, 1614, 1617, 1600, 1615, 1617, 1600, + 1616, 1617, 1591, 1609, 1591, 1610, 1593, 1609, + 1593, 1610, 1594, 1609, 1594, 1610, 1587, 1609, + 1587, 1610, 1588, 1609, 1588, 1610, 1581, 1609, + 1581, 1610, 1580, 1609, 1580, 1610, 1582, 1609, + 1582, 1610, 1589, 1609, 1589, 1610, 1590, 1609, + 1590, 1610, 1588, 1580, 1588, 1581, 1588, 1582, + 1588, 1585, 1587, 1585, 1589, 1585, 1590, 1585, + 1575, 1611, 1578, 1580, 1605, 1578, 1581, 1580, + 1578, 1581, 1605, 1578, 1582, 1605, 1578, 1605, + 1580, 1578, 1605, 1581, 1578, 1605, 1582, 1580, + 1605, 1581, 1581, 1605, 1610, 1581, 1605, 1609, + 1587, 1581, 1580, 1587, 1580, 1581, 1587, 1580, + 1609, 1587, 1605, 1581, 1587, 1605, 1580, 1587, + 1605, 1605, 1589, 1581, 1581, 1589, 1605, 1605, + 1588, 1581, 1605, 1588, 1580, 1610, 1588, 1605, + 1582, 1588, 1605, 1605, 1590, 1581, 1609, 1590, + 1582, 1605, 1591, 1605, 1581, 1591, 1605, 1605, + 1591, 1605, 1610, 1593, 1580, 1605, 1593, 1605, + 1605, 1593, 1605, 1609, 1594, 1605, 1605, 1594, + 1605, 1610, 1594, 1605, 1609, 1601, 1582, 1605, + 1602, 1605, 1581, 1602, 1605, 1605, 1604, 1581, + 1605, 1604, 1581, 1610, 1604, 1581, 1609, 1604, + 1580, 1580, 1604, 1582, 1605, 1604, 1605, 1581, + 1605, 1581, 1580, 1605, 1581, 1605, 1605, 1581, + 1610, 1605, 1580, 1581, 1605, 1580, 1605, 1605, + 1582, 1580, 1605, 1582, 1605, 1605, 1580, 1582, + 1607, 1605, 1580, 1607, 1605, 1605, 1606, 1581, + 1605, 1606, 1581, 1609, 1606, 1580, 1605, 1606, + 1580, 1609, 1606, 1605, 1610, 1606, 1605, 1609, + 1610, 1605, 1605, 1576, 1582, 1610, 1578, 1580, + 1610, 1578, 1580, 1609, 1578, 1582, 1610, 1578, + 1582, 1609, 1578, 1605, 1610, 1578, 1605, 1609, + 1580, 1605, 1610, 1580, 1581, 1609, 1580, 1605, + 1609, 1587, 1582, 1609, 1589, 1581, 1610, 1588, + 1581, 1610, 1590, 1581, 1610, 1604, 1580, 1610, + 1604, 1605, 1610, 1610, 1581, 1610, 1610, 1580, + 1610, 1610, 1605, 1610, 1605, 1605, 1610, 1602, + 1605, 1610, 1606, 1581, 1610, 1593, 1605, 1610, + 1603, 1605, 1610, 1606, 1580, 1581, 1605, 1582, + 1610, 1604, 1580, 1605, 1603, 1605, 1605, 1580, + 1581, 1610, 1581, 1580, 1610, 1605, 1580, 1610, + 1601, 1605, 1610, 1576, 1581, 1610, 1587, 1582, + 1610, 1606, 1580, 1610, 1589, 1604, 1746, 1602, + 1604, 1746, 3, 1575, 1604, 1604, 1607, 3, + 1575, 1603, 1576, 1585, 3, 1605, 1581, 1605, + 1583, 3, 1589, 1604, 1593, 1605, 3, 1585, + 1587, 1608, 1604, 3, 1593, 1604, 1610, 1607, + 3, 1608, 1587, 1604, 1605, 1589, 1604, 1609, + 17, 1589, 1604, 1609, 32, 1575, 1604, 1604, + 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, + 1587, 1604, 1605, 7, 1580, 1604, 32, 1580, + 1604, 1575, 1604, 1607, 3, 1585, 1740, 1575, + 1604, 44, 12289, 12290, 58, 33, 63, 12310, + 12311, 8230, 8229, 8212, 8211, 95, 123, 125, + 12308, 12309, 12304, 12305, 12298, 12299, 12300, 12301, + 12302, 12303, 91, 93, 8254, 35, 38, 42, + 45, 60, 62, 92, 36, 37, 64, 32, + 1611, 1600, 1611, 32, 1612, 32, 1613, 32, + 1614, 1600, 1614, 32, 1615, 1600, 1615, 32, + 1616, 1600, 1616, 32, 1617, 1600, 1617, 32, + 1618, 1600, 1618, 1569, 1570, 1571, 1572, 1573, + 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, + 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, + 1590, 1591, 1592, 1593, 1594, 1601, 1602, 1603, + 1604, 1605, 1606, 1607, 1608, 1610, 1604, 1570, + 1604, 1571, 1604, 1573, 1604, 1575, 34, 39, + 47, 65345, 65346, 65347, 65348, 65349, 65350, 65351, + 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359, + 65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, + 65368, 65369, 65370, 94, 124, 126, 10629, 10630, + 12539, 12449, 12451, 12453, 12455, 12457, 12515, 12517, + 12519, 12483, 12540, 12531, 12441, 12442, 12644, 12593, + 12594, 12595, 12596, 12597, 12598, 12599, 12600, 12601, + 12602, 12603, 12604, 12605, 12606, 12607, 12608, 12609, + 12610, 12611, 12612, 12613, 12614, 12615, 12616, 12617, + 12618, 12619, 12620, 12621, 12622, 12623, 12624, 12625, + 12626, 12627, 12628, 12629, 12630, 12631, 12632, 12633, + 12634, 12635, 12636, 12637, 12638, 12639, 12640, 12641, + 12642, 12643, 162, 163, 172, 175, 166, 165, + 8361, 9474, 8592, 8593, 8594, 8595, 9632, 9675, + 55297, 56360, 55297, 56361, 55297, 56362, 55297, 56363, + 55297, 56364, 55297, 56365, 55297, 56366, 55297, 56367, + 55297, 56368, 55297, 56369, 55297, 56370, 55297, 56371, + 55297, 56372, 55297, 56373, 55297, 56374, 55297, 56375, + 55297, 56376, 55297, 56377, 55297, 56378, 55297, 56379, + 55297, 56380, 55297, 56381, 55297, 56382, 55297, 56383, + 55297, 56384, 55297, 56385, 55297, 56386, 55297, 56387, + 55297, 56388, 55297, 56389, 55297, 56390, 55297, 56391, + 55297, 56392, 55297, 56393, 55297, 56394, 55297, 56395, + 55297, 56396, 55297, 56397, 55297, 56398, 55297, 56399, + 55297, 56536, 55297, 56537, 55297, 56538, 55297, 56539, + 55297, 56540, 55297, 56541, 55297, 56542, 55297, 56543, + 55297, 56544, 55297, 56545, 55297, 56546, 55297, 56547, + 55297, 56548, 55297, 56549, 55297, 56550, 55297, 56551, + 55297, 56552, 55297, 56553, 55297, 56554, 55297, 56555, + 55297, 56556, 55297, 56557, 55297, 56558, 55297, 56559, + 55297, 56560, 55297, 56561, 55297, 56562, 55297, 56563, + 55297, 56564, 55297, 56565, 55297, 56566, 55297, 56567, + 55297, 56568, 55297, 56569, 55297, 56570, 55297, 56571, + 55297, 56727, 55297, 56728, 55297, 56729, 55297, 56730, + 55297, 56731, 55297, 56732, 55297, 56733, 55297, 56734, + 55297, 56735, 55297, 56736, 55297, 56737, 55297, 56739, + 55297, 56740, 55297, 56741, 55297, 56742, 55297, 56743, + 55297, 56744, 55297, 56745, 55297, 56746, 55297, 56747, + 55297, 56748, 55297, 56749, 55297, 56750, 55297, 56751, + 55297, 56752, 55297, 56753, 55297, 56755, 55297, 56756, + 55297, 56757, 55297, 56758, 55297, 56759, 55297, 56760, + 55297, 56761, 55297, 56763, 55297, 56764, 720, 721, + 665, 675, 43878, 677, 676, 7569, 600, 606, + 681, 612, 610, 667, 668, 615, 644, 682, + 683, 55351, 57092, 42894, 622, 55351, 57093, 654, + 55351, 57094, 630, 631, 634, 55351, 57096, 638, + 680, 678, 43879, 679, 11377, 655, 673, 674, + 664, 448, 449, 450, 55351, 57098, 55351, 57118, + 55299, 56512, 55299, 56513, 55299, 56514, 55299, 56515, + 55299, 56516, 55299, 56517, 55299, 56518, 55299, 56519, + 55299, 56520, 55299, 56521, 55299, 56522, 55299, 56523, + 55299, 56524, 55299, 56525, 55299, 56526, 55299, 56527, + 55299, 56528, 55299, 56529, 55299, 56530, 55299, 56531, + 55299, 56532, 55299, 56533, 55299, 56534, 55299, 56535, + 55299, 56536, 55299, 56537, 55299, 56538, 55299, 56539, + 55299, 56540, 55299, 56541, 55299, 56542, 55299, 56543, + 55299, 56544, 55299, 56545, 55299, 56546, 55299, 56547, + 55299, 56548, 55299, 56549, 55299, 56550, 55299, 56551, + 55299, 56552, 55299, 56553, 55299, 56554, 55299, 56555, + 55299, 56556, 55299, 56557, 55299, 56558, 55299, 56559, + 55299, 56560, 55299, 56561, 55299, 56562, 55300, 56473, + 55300, 56506, 55300, 56475, 55300, 56506, 55300, 56485, + 55300, 56506, 55300, 56625, 55300, 56615, 55300, 56626, + 55300, 56615, 55300, 57159, 55300, 57150, 55300, 57159, + 55300, 57175, 55301, 56505, 55301, 56506, 55301, 56505, + 55301, 56496, 55301, 56505, 55301, 56509, 55301, 56760, + 55301, 56751, 55301, 56761, 55301, 56751, 55302, 56512, + 55302, 56513, 55302, 56514, 55302, 56515, 55302, 56516, + 55302, 56517, 55302, 56518, 55302, 56519, 55302, 56520, + 55302, 56521, 55302, 56522, 55302, 56523, 55302, 56524, + 55302, 56525, 55302, 56526, 55302, 56527, 55302, 56528, + 55302, 56529, 55302, 56530, 55302, 56531, 55302, 56532, + 55302, 56533, 55302, 56534, 55302, 56535, 55302, 56536, + 55302, 56537, 55302, 56538, 55302, 56539, 55302, 56540, + 55302, 56541, 55302, 56542, 55302, 56543, 55302, 56629, + 55302, 56624, 55323, 56928, 55323, 56929, 55323, 56930, + 55323, 56931, 55323, 56932, 55323, 56933, 55323, 56934, + 55323, 56935, 55323, 56936, 55323, 56937, 55323, 56938, + 55323, 56939, 55323, 56940, 55323, 56941, 55323, 56942, + 55323, 56943, 55323, 56944, 55323, 56945, 55323, 56946, + 55323, 56947, 55323, 56948, 55323, 56949, 55323, 56950, + 55323, 56951, 55323, 56952, 55323, 56953, 55323, 56954, + 55323, 56955, 55323, 56956, 55323, 56957, 55323, 56958, + 55323, 56959, 55348, 56663, 55348, 56677, 55348, 56664, + 55348, 56677, 55348, 56671, 55348, 56686, 55348, 56671, + 55348, 56687, 55348, 56671, 55348, 56688, 55348, 56671, + 55348, 56689, 55348, 56671, 55348, 56690, 55348, 56761, + 55348, 56677, 55348, 56762, 55348, 56677, 55348, 56763, + 55348, 56686, 55348, 56764, 55348, 56686, 55348, 56763, + 55348, 56687, 55348, 56764, 55348, 56687, 305, 567, + 913, 914, 916, 917, 918, 919, 921, 922, + 923, 924, 925, 926, 927, 929, 1012, 932, + 934, 935, 936, 8711, 8706, 1013, 977, 1008, + 981, 1009, 982, 988, 55354, 56610, 55354, 56611, + 55354, 56612, 55354, 56613, 55354, 56614, 55354, 56615, + 55354, 56616, 55354, 56617, 55354, 56618, 55354, 56619, + 55354, 56620, 55354, 56621, 55354, 56622, 55354, 56623, + 55354, 56624, 55354, 56625, 55354, 56626, 55354, 56627, + 55354, 56628, 55354, 56629, 55354, 56630, 55354, 56631, + 55354, 56632, 55354, 56633, 55354, 56634, 55354, 56635, + 55354, 56636, 55354, 56637, 55354, 56638, 55354, 56639, + 55354, 56640, 55354, 56641, 55354, 56642, 55354, 56643, + 1646, 1697, 1647, 48, 46, 48, 44, 49, + 44, 50, 44, 51, 44, 52, 44, 53, + 44, 54, 44, 55, 44, 56, 44, 57, + 44, 40, 65, 41, 40, 66, 41, 40, + 67, 41, 40, 68, 41, 40, 69, 41, + 40, 70, 41, 40, 71, 41, 40, 72, + 41, 40, 73, 41, 40, 74, 41, 40, + 75, 41, 40, 76, 41, 40, 77, 41, + 40, 78, 41, 40, 79, 41, 40, 80, + 41, 40, 81, 41, 40, 82, 41, 40, + 83, 41, 40, 84, 41, 40, 85, 41, + 40, 86, 41, 40, 87, 41, 40, 88, + 41, 40, 89, 41, 40, 90, 41, 12308, + 83, 12309, 67, 68, 87, 90, 72, 86, + 83, 68, 83, 83, 80, 80, 86, 87, + 67, 77, 67, 77, 68, 77, 82, 68, + 74, 12411, 12363, 12467, 12467, 23383, 21452, 12487, + 22810, 35299, 20132, 26144, 28961, 21069, 24460, 20877, + 26032, 21021, 32066, 36009, 22768, 21561, 28436, 25237, + 25429, 36938, 25351, 25171, 31105, 31354, 21512, 28288, + 30003, 21106, 21942, 37197, 12308, 26412, 12309, 12308, + 19977, 12309, 12308, 20108, 12309, 12308, 23433, 12309, + 12308, 28857, 12309, 12308, 25171, 12309, 12308, 30423, + 12309, 12308, 21213, 12309, 12308, 25943, 12309, 24471, + 21487, 20029, 20024, 20033, 55360, 56610, 20320, 20411, + 20482, 20602, 20633, 20687, 13470, 55361, 56890, 20820, + 20836, 20855, 55361, 56604, 13497, 20839, 55361, 56651, + 20887, 20900, 20172, 20908, 55396, 56799, 20995, 13535, + 21051, 21062, 21111, 13589, 21253, 21254, 21321, 21338, + 21363, 21373, 21375, 55362, 56876, 28784, 21450, 21471, + 55362, 57187, 21483, 21489, 21510, 21662, 21560, 21576, + 21608, 21666, 21750, 21776, 21843, 21859, 21892, 21931, + 21939, 21954, 22294, 22295, 22097, 22132, 22766, 22478, + 22516, 22541, 22411, 22578, 22577, 22700, 55365, 56548, + 22770, 22775, 22790, 22818, 22882, 55365, 57000, 55365, + 57066, 23020, 23067, 23079, 23000, 23142, 14062, 14076, + 23304, 23358, 55366, 56776, 23491, 23512, 23539, 55366, + 57112, 23551, 23558, 24403, 14209, 23648, 23744, 23693, + 55367, 56804, 23875, 55367, 56806, 23918, 23915, 23932, + 24033, 24034, 14383, 24061, 24104, 24125, 24169, 14434, + 55368, 56707, 14460, 24240, 24243, 24246, 55400, 57234, + 55368, 57137, 33281, 24354, 14535, 55372, 57016, 55384, + 56794, 24418, 24427, 14563, 24474, 24525, 24535, 24569, + 24705, 14650, 14620, 55369, 57044, 24775, 24904, 24908, + 24954, 25010, 24996, 25007, 25054, 25104, 25115, 25181, + 25265, 25300, 25424, 55370, 57100, 25405, 25340, 25448, + 25475, 25572, 55370, 57329, 25634, 25541, 25513, 14894, + 25705, 25726, 25757, 25719, 14956, 25964, 55372, 56330, + 26083, 26360, 26185, 15129, 15112, 15076, 20882, 20885, + 26368, 26268, 32941, 17369, 26401, 26462, 26451, 55372, + 57283, 15177, 26618, 26501, 26706, 55373, 56429, 26766, + 26655, 26900, 26946, 27043, 27114, 27304, 55373, 56995, + 27355, 15384, 27425, 55374, 56487, 27476, 15438, 27506, + 27551, 27579, 55374, 56973, 55367, 56587, 55374, 57082, + 27726, 55375, 56508, 27839, 27853, 27751, 27926, 27966, + 28009, 28024, 28037, 55375, 56606, 27956, 28207, 28270, + 15667, 28359, 55375, 57041, 28153, 28526, 55375, 57182, + 55375, 57230, 28614, 28729, 28699, 15766, 28746, 28797, + 28791, 28845, 55361, 56613, 28997, 55376, 56931, 29084, + 55376, 57259, 29224, 29264, 55377, 56840, 29312, 29333, + 55377, 57141, 55378, 56340, 29562, 29579, 16044, 29605, + 16056, 29767, 29788, 29829, 29898, 16155, 29988, 55379, + 56374, 30014, 55379, 56466, 55368, 56735, 30224, 55379, + 57249, 55379, 57272, 55380, 56388, 16380, 16392, 55380, + 56563, 55380, 56562, 55380, 56601, 55380, 56627, 30494, + 30495, 30603, 16454, 16534, 55381, 56349, 30798, 16611, + 55381, 56870, 55381, 56986, 55381, 57029, 31211, 16687, + 31306, 31311, 55382, 56700, 55382, 56999, 31470, 16898, + 55382, 57259, 31686, 31689, 16935, 55383, 56448, 31954, + 17056, 31976, 31971, 32000, 55383, 57222, 32099, 17153, + 32199, 32258, 32325, 17204, 55384, 56872, 55384, 56903, + 17241, 55384, 57049, 32634, 55384, 57150, 32661, 32762, + 55385, 56538, 55385, 56611, 32864, 55385, 56744, 32880, + 55372, 57183, 17365, 32946, 33027, 17419, 33086, 23221, + 55385, 57255, 55385, 57269, 55372, 57235, 55372, 57244, + 33284, 36766, 17515, 33425, 33419, 33437, 21171, 33457, + 33459, 33469, 33510, 55386, 57148, 33565, 33635, 33709, + 33571, 33725, 33767, 33619, 33738, 33740, 33756, 55387, + 56374, 55387, 56683, 55387, 56533, 17707, 34033, 34035, + 34070, 55388, 57290, 34148, 55387, 57132, 17757, 17761, + 55387, 57265, 55388, 56530, 17771, 34384, 34407, 34409, + 34473, 34440, 34574, 34530, 34600, 34667, 34694, 17879, + 34785, 34817, 17913, 34912, 55389, 56935, 35031, 35038, + 17973, 35066, 13499, 55390, 56494, 55390, 56678, 18110, + 18119, 35488, 55391, 56488, 36011, 36033, 36123, 36215, + 55391, 57135, 55362, 56324, 36299, 36284, 36336, 55362, + 56542, 36564, 55393, 56786, 55393, 56813, 37012, 37105, + 37137, 55393, 57134, 37147, 37432, 37591, 37592, 37500, + 37881, 37909, 55394, 57338, 38283, 18837, 38327, 55395, + 56695, 18918, 38595, 23986, 38691, 55396, 56645, 55396, + 56858, 19054, 19062, 38880, 55397, 56330, 19122, 55397, + 56470, 38953, 55397, 56758, 39138, 19251, 39209, 39335, + 39362, 39422, 19406, 55398, 57136, 40000, 40189, 19662, + 19693, 40295, 55400, 56526, 19704, 55400, 56581, 55400, + 56846, 55400, 56977, 19798, 40702, 40709, 40719, 40726, + 55401, 56832, 170, 186, 7838, 192, 193, 194, + 195, 196, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 216, 217, 218, 219, 220, 221, + 222, 376, 256, 258, 260, 262, 264, 266, + 268, 270, 272, 274, 276, 278, 280, 282, + 284, 286, 288, 290, 292, 296, 298, 300, + 302, 306, 308, 310, 312, 313, 315, 317, + 319, 321, 323, 325, 327, 329, 330, 332, + 334, 336, 338, 340, 342, 344, 346, 348, + 350, 352, 354, 356, 358, 360, 362, 364, + 366, 368, 370, 372, 374, 377, 379, 381, + 579, 386, 388, 391, 395, 397, 401, 502, + 408, 573, 411, 544, 416, 418, 420, 423, + 426, 428, 431, 435, 437, 440, 442, 444, + 446, 503, 453, 452, 456, 455, 459, 458, + 461, 463, 465, 467, 469, 471, 473, 475, + 478, 480, 482, 484, 486, 488, 490, 492, + 494, 496, 498, 497, 500, 504, 506, 508, + 510, 512, 514, 516, 518, 520, 522, 524, + 526, 528, 530, 532, 534, 536, 538, 540, + 542, 545, 548, 550, 552, 554, 556, 558, + 560, 562, 564, 565, 566, 568, 569, 571, + 11390, 11391, 577, 582, 584, 586, 588, 590, + 11375, 11373, 11376, 385, 390, 393, 394, 399, + 602, 42923, 605, 403, 42924, 404, 42893, 42922, + 407, 406, 42926, 11362, 42925, 412, 11374, 413, + 415, 636, 11364, 639, 422, 42949, 425, 645, + 646, 42929, 430, 580, 433, 434, 581, 439, + 659, 662, 663, 666, 42930, 42928, 672, 684, + 685, 686, 687, 688, 689, 690, 691, 692, + 693, 694, 695, 696, 704, 705, 736, 737, + 738, 739, 740, 880, 882, 886, 890, 1021, + 1022, 1023, 938, 939, 978, 979, 980, 975, + 984, 986, 990, 992, 994, 996, 998, 1000, + 1002, 1004, 1006, 1017, 895, 1015, 1018, 1020, + 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, + 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, + 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, + 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, + 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, + 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, + 1120, 1122, 1124, 1126, 1128, 1130, 1132, 1134, + 1136, 1138, 1140, 1142, 1144, 1146, 1148, 1150, + 1152, 1162, 1164, 1166, 1168, 1170, 1172, 1174, + 1176, 1178, 1180, 1182, 1184, 1186, 1188, 1190, + 1192, 1194, 1196, 1198, 1200, 1202, 1204, 1206, + 1208, 1210, 1212, 1214, 1217, 1219, 1221, 1223, + 1225, 1227, 1229, 1216, 1232, 1234, 1236, 1238, + 1240, 1242, 1244, 1246, 1248, 1250, 1252, 1254, + 1256, 1258, 1260, 1262, 1264, 1266, 1268, 1270, + 1272, 1274, 1276, 1278, 1280, 1282, 1284, 1286, + 1288, 1290, 1292, 1294, 1296, 1298, 1300, 1302, + 1304, 1306, 1308, 1310, 1312, 1314, 1316, 1318, + 1320, 1322, 1324, 1326, 1376, 1329, 1330, 1331, + 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, + 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, + 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, + 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, + 1364, 1365, 1366, 1415, 1416, 7312, 7313, 7314, + 7315, 7316, 7317, 7318, 7319, 7320, 7321, 7322, + 7323, 7324, 7325, 7326, 7327, 7328, 7329, 7330, + 7331, 7332, 7333, 7334, 7335, 7336, 7337, 7338, + 7339, 7340, 7341, 7342, 7343, 7344, 7345, 7346, + 7347, 7348, 7349, 7350, 7351, 7352, 7353, 7354, + 4348, 7357, 7358, 7359, 43888, 43889, 43890, 43891, + 43892, 43893, 43894, 43895, 43896, 43897, 43898, 43899, + 43900, 43901, 43902, 43903, 43904, 43905, 43906, 43907, + 43908, 43909, 43910, 43911, 43912, 43913, 43914, 43915, + 43916, 43917, 43918, 43919, 43920, 43921, 43922, 43923, + 43924, 43925, 43926, 43927, 43928, 43929, 43930, 43931, + 43932, 43933, 43934, 43935, 43936, 43937, 43938, 43939, + 43940, 43941, 43942, 43943, 43944, 43945, 43946, 43947, + 43948, 43949, 43950, 43951, 43952, 43953, 43954, 43955, + 43956, 43957, 43958, 43959, 43960, 43961, 43962, 43963, + 43964, 43965, 43966, 43967, 5112, 5113, 5114, 5115, + 5116, 5117, 42570, 7424, 7425, 7427, 7428, 7429, + 7430, 7431, 7432, 7433, 7434, 7435, 7436, 7437, + 7438, 7439, 7440, 7441, 7442, 7443, 7444, 7445, + 7448, 7449, 7450, 7451, 7454, 7455, 7456, 7457, + 7458, 7459, 7460, 7462, 7463, 7464, 7465, 7466, + 7467, 7468, 7469, 7470, 7471, 7472, 7473, 7474, + 7475, 7476, 7477, 7478, 7479, 7480, 7481, 7482, + 7483, 7484, 7485, 7486, 7487, 7488, 7489, 7490, + 7491, 7492, 7493, 7494, 7495, 7496, 7497, 7498, + 7499, 7500, 7501, 7502, 7503, 7504, 7505, 7506, + 7507, 7508, 7509, 7510, 7511, 7512, 7513, 7514, + 7515, 7516, 7517, 7518, 7519, 7520, 7521, 7522, + 7523, 7524, 7525, 7526, 7527, 7528, 7529, 7530, + 7531, 7532, 7533, 7534, 7535, 7536, 7537, 7538, + 7539, 7540, 7541, 7542, 7543, 7544, 42877, 7546, + 7548, 11363, 7550, 7551, 7552, 7553, 7554, 7555, + 7556, 7558, 7559, 7560, 7561, 7562, 7563, 7564, + 7565, 42950, 7567, 7568, 7570, 7571, 7572, 7573, + 7574, 7575, 7576, 7577, 7578, 7579, 7580, 7581, + 7582, 7583, 7584, 7585, 7586, 7587, 7588, 7589, + 7590, 7591, 7592, 7593, 7594, 7595, 7596, 7597, + 7598, 7599, 7600, 7601, 7602, 7603, 7604, 7605, + 7606, 7607, 7608, 7609, 7610, 7611, 7612, 7613, + 7614, 7615, 7680, 7682, 7684, 7686, 7688, 7690, + 7692, 7694, 7696, 7698, 7700, 7702, 7704, 7706, + 7708, 7710, 7712, 7714, 7716, 7718, 7720, 7722, + 7724, 7726, 7728, 7730, 7732, 7734, 7736, 7738, + 7740, 7742, 7744, 7746, 7748, 7750, 7752, 7754, + 7756, 7758, 7760, 7762, 7764, 7766, 7768, 7770, + 7772, 7774, 7776, 7778, 7780, 7782, 7784, 7786, + 7788, 7790, 7792, 7794, 7796, 7798, 7800, 7802, + 7804, 7806, 7808, 7810, 7812, 7814, 7816, 7818, + 7820, 7822, 7824, 7826, 7828, 7830, 7831, 7832, + 7833, 7834, 7836, 7837, 223, 7839, 7840, 7842, + 7844, 7846, 7848, 7850, 7852, 7854, 7856, 7858, + 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, + 7876, 7878, 7880, 7882, 7884, 7886, 7888, 7890, + 7892, 7894, 7896, 7898, 7900, 7902, 7904, 7906, + 7908, 7910, 7912, 7914, 7916, 7918, 7920, 7922, + 7924, 7926, 7928, 7930, 7932, 7934, 7944, 7945, + 7946, 7947, 7948, 7949, 7950, 7951, 7960, 7961, + 7962, 7963, 7964, 7965, 7976, 7977, 7978, 7979, + 7980, 7981, 7982, 7983, 7992, 7993, 7994, 7995, + 7996, 7997, 7998, 7999, 8008, 8009, 8010, 8011, + 8012, 8013, 8016, 8025, 8018, 8027, 8020, 8029, + 8022, 8031, 8040, 8041, 8042, 8043, 8044, 8045, + 8046, 8047, 8122, 8123, 8136, 8137, 8138, 8139, + 8154, 8155, 8184, 8185, 8170, 8171, 8186, 8187, + 8072, 8073, 8074, 8075, 8076, 8077, 8078, 8079, + 8064, 8065, 8066, 8067, 8068, 8069, 8070, 8071, + 8088, 8089, 8090, 8091, 8092, 8093, 8094, 8095, + 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, + 8104, 8105, 8106, 8107, 8108, 8109, 8110, 8111, + 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103, + 8120, 8121, 8114, 8124, 8116, 8118, 8119, 8115, + 8130, 8140, 8132, 8134, 8135, 8131, 8152, 8153, + 8146, 8147, 8150, 8151, 8168, 8169, 8162, 8163, + 8164, 8172, 8166, 8167, 8178, 8188, 8180, 8182, + 8183, 8179, 8305, 8319, 8336, 8337, 8338, 8339, + 8340, 8341, 8342, 8343, 8344, 8345, 8346, 8347, + 8348, 8450, 8455, 8458, 8459, 8460, 8461, 8462, + 8463, 8464, 8465, 8466, 8467, 8469, 8473, 8474, + 8475, 8476, 8477, 8484, 8488, 8492, 8493, 8495, + 8496, 8497, 8499, 8500, 8505, 8508, 8509, 8510, + 8511, 8517, 8518, 8519, 8520, 8521, 8498, 8544, + 8545, 8546, 8547, 8548, 8549, 8550, 8551, 8552, + 8553, 8554, 8555, 8556, 8557, 8558, 8559, 8579, + 9398, 9399, 9400, 9401, 9402, 9403, 9404, 9405, + 9406, 9407, 9408, 9409, 9410, 9411, 9412, 9413, + 9414, 9415, 9416, 9417, 9418, 9419, 9420, 9421, + 9422, 9423, 11264, 11265, 11266, 11267, 11268, 11269, + 11270, 11271, 11272, 11273, 11274, 11275, 11276, 11277, + 11278, 11279, 11280, 11281, 11282, 11283, 11284, 11285, + 11286, 11287, 11288, 11289, 11290, 11291, 11292, 11293, + 11294, 11295, 11296, 11297, 11298, 11299, 11300, 11301, + 11302, 11303, 11304, 11305, 11306, 11307, 11308, 11309, + 11310, 11311, 11360, 570, 574, 11367, 11369, 11371, + 11378, 11380, 11381, 11383, 11384, 11385, 11386, 11387, + 11388, 11389, 11392, 11394, 11396, 11398, 11400, 11402, + 11404, 11406, 11408, 11410, 11412, 11414, 11416, 11418, + 11420, 11422, 11424, 11426, 11428, 11430, 11432, 11434, + 11436, 11438, 11440, 11442, 11444, 11446, 11448, 11450, + 11452, 11454, 11456, 11458, 11460, 11462, 11464, 11466, + 11468, 11470, 11472, 11474, 11476, 11478, 11480, 11482, + 11484, 11486, 11488, 11490, 11492, 11499, 11501, 11506, + 4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, + 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, + 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, + 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287, + 4288, 4289, 4290, 4291, 4292, 4293, 4295, 4301, + 42560, 42562, 42564, 42566, 42568, 42572, 42574, 42576, + 42578, 42580, 42582, 42584, 42586, 42588, 42590, 42592, + 42594, 42596, 42598, 42600, 42602, 42604, 42624, 42626, + 42628, 42630, 42632, 42634, 42636, 42638, 42640, 42642, + 42644, 42646, 42648, 42650, 42652, 42653, 42786, 42788, + 42790, 42792, 42794, 42796, 42798, 42800, 42801, 42802, + 42804, 42806, 42808, 42810, 42812, 42814, 42816, 42818, + 42820, 42822, 42824, 42826, 42828, 42830, 42832, 42834, + 42836, 42838, 42840, 42842, 42844, 42846, 42848, 42850, + 42852, 42854, 42856, 42858, 42860, 42862, 42864, 42865, + 42866, 42867, 42868, 42869, 42870, 42871, 42872, 42873, + 42875, 42878, 42880, 42882, 42884, 42886, 42891, 42896, + 42898, 42948, 42901, 42902, 42904, 42906, 42908, 42910, + 42912, 42914, 42916, 42918, 42920, 42927, 42932, 42934, + 42936, 42938, 42940, 42942, 42944, 42946, 42951, 42953, + 42960, 42963, 42965, 42966, 42968, 42994, 42995, 42996, + 42997, 43000, 43001, 43002, 43824, 43825, 43826, 43827, + 43828, 43829, 43830, 43832, 43833, 43834, 43835, 43836, + 43837, 43838, 43839, 43840, 43841, 43842, 43843, 43844, + 43845, 43846, 43847, 43848, 43849, 43850, 43851, 43852, + 43853, 43854, 43855, 43856, 43857, 42931, 43860, 43861, + 43862, 43863, 43864, 43865, 43866, 43868, 43869, 43870, + 43871, 43872, 43873, 43874, 43875, 43876, 43877, 43880, + 43881, 64256, 64257, 64258, 64259, 64260, 64261, 64262, + 64275, 64276, 64277, 64278, 64279, 65313, 65314, 65315, + 65316, 65317, 65318, 65319, 65320, 65321, 65322, 65323, + 65324, 65325, 65326, 65327, 65328, 65329, 65330, 65331, + 65332, 65333, 65334, 65335, 65336, 65337, 65338, 55297, + 56320, 55297, 56321, 55297, 56322, 55297, 56323, 55297, + 56324, 55297, 56325, 55297, 56326, 55297, 56327, 55297, + 56328, 55297, 56329, 55297, 56330, 55297, 56331, 55297, + 56332, 55297, 56333, 55297, 56334, 55297, 56335, 55297, + 56336, 55297, 56337, 55297, 56338, 55297, 56339, 55297, + 56340, 55297, 56341, 55297, 56342, 55297, 56343, 55297, + 56344, 55297, 56345, 55297, 56346, 55297, 56347, 55297, + 56348, 55297, 56349, 55297, 56350, 55297, 56351, 55297, + 56352, 55297, 56353, 55297, 56354, 55297, 56355, 55297, + 56356, 55297, 56357, 55297, 56358, 55297, 56359, 55297, + 56496, 55297, 56497, 55297, 56498, 55297, 56499, 55297, + 56500, 55297, 56501, 55297, 56502, 55297, 56503, 55297, + 56504, 55297, 56505, 55297, 56506, 55297, 56507, 55297, + 56508, 55297, 56509, 55297, 56510, 55297, 56511, 55297, + 56512, 55297, 56513, 55297, 56514, 55297, 56515, 55297, + 56516, 55297, 56517, 55297, 56518, 55297, 56519, 55297, + 56520, 55297, 56521, 55297, 56522, 55297, 56523, 55297, + 56524, 55297, 56525, 55297, 56526, 55297, 56527, 55297, + 56528, 55297, 56529, 55297, 56530, 55297, 56531, 55297, + 56688, 55297, 56689, 55297, 56690, 55297, 56691, 55297, + 56692, 55297, 56693, 55297, 56694, 55297, 56695, 55297, + 56696, 55297, 56697, 55297, 56698, 55297, 56700, 55297, + 56701, 55297, 56702, 55297, 56703, 55297, 56704, 55297, + 56705, 55297, 56706, 55297, 56707, 55297, 56708, 55297, + 56709, 55297, 56710, 55297, 56711, 55297, 56712, 55297, + 56713, 55297, 56714, 55297, 56716, 55297, 56717, 55297, + 56718, 55297, 56719, 55297, 56720, 55297, 56721, 55297, + 56722, 55297, 56724, 55297, 56725, 55297, 57216, 55297, + 57219, 55297, 57220, 55297, 57221, 55297, 57223, 55297, + 57224, 55297, 57225, 55297, 57226, 55297, 57227, 55297, + 57228, 55297, 57229, 55297, 57230, 55297, 57231, 55297, + 57232, 55297, 57233, 55297, 57234, 55297, 57235, 55297, + 57236, 55297, 57237, 55297, 57238, 55297, 57239, 55297, + 57240, 55297, 57241, 55297, 57242, 55297, 57243, 55297, + 57244, 55297, 57245, 55297, 57246, 55297, 57247, 55297, + 57248, 55297, 57249, 55297, 57250, 55297, 57251, 55297, + 57252, 55297, 57253, 55297, 57254, 55297, 57255, 55297, + 57256, 55297, 57257, 55297, 57258, 55297, 57259, 55297, + 57260, 55297, 57261, 55297, 57262, 55297, 57263, 55297, + 57264, 55297, 57266, 55297, 57267, 55297, 57268, 55297, + 57269, 55297, 57270, 55297, 57271, 55297, 57272, 55297, + 57273, 55297, 57274, 55299, 56448, 55299, 56449, 55299, + 56450, 55299, 56451, 55299, 56452, 55299, 56453, 55299, + 56454, 55299, 56455, 55299, 56456, 55299, 56457, 55299, + 56458, 55299, 56459, 55299, 56460, 55299, 56461, 55299, + 56462, 55299, 56463, 55299, 56464, 55299, 56465, 55299, + 56466, 55299, 56467, 55299, 56468, 55299, 56469, 55299, + 56470, 55299, 56471, 55299, 56472, 55299, 56473, 55299, + 56474, 55299, 56475, 55299, 56476, 55299, 56477, 55299, + 56478, 55299, 56479, 55299, 56480, 55299, 56481, 55299, + 56482, 55299, 56483, 55299, 56484, 55299, 56485, 55299, + 56486, 55299, 56487, 55299, 56488, 55299, 56489, 55299, + 56490, 55299, 56491, 55299, 56492, 55299, 56493, 55299, + 56494, 55299, 56495, 55299, 56496, 55299, 56497, 55299, + 56498, 55302, 56480, 55302, 56481, 55302, 56482, 55302, + 56483, 55302, 56484, 55302, 56485, 55302, 56486, 55302, + 56487, 55302, 56488, 55302, 56489, 55302, 56490, 55302, + 56491, 55302, 56492, 55302, 56493, 55302, 56494, 55302, + 56495, 55302, 56496, 55302, 56497, 55302, 56498, 55302, + 56499, 55302, 56500, 55302, 56501, 55302, 56502, 55302, + 56503, 55302, 56504, 55302, 56505, 55302, 56506, 55302, + 56507, 55302, 56508, 55302, 56509, 55302, 56510, 55302, + 56511, 55323, 56896, 55323, 56897, 55323, 56898, 55323, + 56899, 55323, 56900, 55323, 56901, 55323, 56902, 55323, + 56903, 55323, 56904, 55323, 56905, 55323, 56906, 55323, + 56907, 55323, 56908, 55323, 56909, 55323, 56910, 55323, + 56911, 55323, 56912, 55323, 56913, 55323, 56914, 55323, + 56915, 55323, 56916, 55323, 56917, 55323, 56918, 55323, + 56919, 55323, 56920, 55323, 56921, 55323, 56922, 55323, + 56923, 55323, 56924, 55323, 56925, 55323, 56926, 55323, + 56927, 55349, 56320, 55349, 56321, 55349, 56322, 55349, + 56323, 55349, 56324, 55349, 56325, 55349, 56326, 55349, + 56327, 55349, 56328, 55349, 56329, 55349, 56330, 55349, + 56331, 55349, 56332, 55349, 56333, 55349, 56334, 55349, + 56335, 55349, 56336, 55349, 56337, 55349, 56338, 55349, + 56339, 55349, 56340, 55349, 56341, 55349, 56342, 55349, + 56343, 55349, 56344, 55349, 56345, 55349, 56346, 55349, + 56347, 55349, 56348, 55349, 56349, 55349, 56350, 55349, + 56351, 55349, 56352, 55349, 56353, 55349, 56354, 55349, + 56355, 55349, 56356, 55349, 56357, 55349, 56358, 55349, + 56359, 55349, 56360, 55349, 56361, 55349, 56362, 55349, + 56363, 55349, 56364, 55349, 56365, 55349, 56366, 55349, + 56367, 55349, 56368, 55349, 56369, 55349, 56370, 55349, + 56371, 55349, 56372, 55349, 56373, 55349, 56374, 55349, + 56375, 55349, 56376, 55349, 56377, 55349, 56378, 55349, + 56379, 55349, 56380, 55349, 56381, 55349, 56382, 55349, + 56383, 55349, 56384, 55349, 56385, 55349, 56386, 55349, + 56387, 55349, 56388, 55349, 56389, 55349, 56390, 55349, + 56391, 55349, 56392, 55349, 56393, 55349, 56394, 55349, + 56395, 55349, 56396, 55349, 56397, 55349, 56398, 55349, + 56399, 55349, 56400, 55349, 56401, 55349, 56402, 55349, + 56403, 55349, 56404, 55349, 56406, 55349, 56407, 55349, + 56408, 55349, 56409, 55349, 56410, 55349, 56411, 55349, + 56412, 55349, 56413, 55349, 56414, 55349, 56415, 55349, + 56416, 55349, 56417, 55349, 56418, 55349, 56419, 55349, + 56420, 55349, 56421, 55349, 56422, 55349, 56423, 55349, + 56424, 55349, 56425, 55349, 56426, 55349, 56427, 55349, + 56428, 55349, 56429, 55349, 56430, 55349, 56431, 55349, + 56432, 55349, 56433, 55349, 56434, 55349, 56435, 55349, + 56436, 55349, 56437, 55349, 56438, 55349, 56439, 55349, + 56440, 55349, 56441, 55349, 56442, 55349, 56443, 55349, + 56444, 55349, 56445, 55349, 56446, 55349, 56447, 55349, + 56448, 55349, 56449, 55349, 56450, 55349, 56451, 55349, + 56452, 55349, 56453, 55349, 56454, 55349, 56455, 55349, + 56456, 55349, 56457, 55349, 56458, 55349, 56459, 55349, + 56460, 55349, 56461, 55349, 56462, 55349, 56463, 55349, + 56464, 55349, 56465, 55349, 56466, 55349, 56467, 55349, + 56468, 55349, 56469, 55349, 56470, 55349, 56471, 55349, + 56472, 55349, 56473, 55349, 56474, 55349, 56475, 55349, + 56476, 55349, 56478, 55349, 56479, 55349, 56482, 55349, + 56485, 55349, 56486, 55349, 56489, 55349, 56490, 55349, + 56491, 55349, 56492, 55349, 56494, 55349, 56495, 55349, + 56496, 55349, 56497, 55349, 56498, 55349, 56499, 55349, + 56500, 55349, 56501, 55349, 56502, 55349, 56503, 55349, + 56504, 55349, 56505, 55349, 56507, 55349, 56509, 55349, + 56510, 55349, 56511, 55349, 56512, 55349, 56513, 55349, + 56514, 55349, 56515, 55349, 56517, 55349, 56518, 55349, + 56519, 55349, 56520, 55349, 56521, 55349, 56522, 55349, + 56523, 55349, 56524, 55349, 56525, 55349, 56526, 55349, + 56527, 55349, 56528, 55349, 56529, 55349, 56530, 55349, + 56531, 55349, 56532, 55349, 56533, 55349, 56534, 55349, + 56535, 55349, 56536, 55349, 56537, 55349, 56538, 55349, + 56539, 55349, 56540, 55349, 56541, 55349, 56542, 55349, + 56543, 55349, 56544, 55349, 56545, 55349, 56546, 55349, + 56547, 55349, 56548, 55349, 56549, 55349, 56550, 55349, + 56551, 55349, 56552, 55349, 56553, 55349, 56554, 55349, + 56555, 55349, 56556, 55349, 56557, 55349, 56558, 55349, + 56559, 55349, 56560, 55349, 56561, 55349, 56562, 55349, + 56563, 55349, 56564, 55349, 56565, 55349, 56566, 55349, + 56567, 55349, 56568, 55349, 56569, 55349, 56570, 55349, + 56571, 55349, 56572, 55349, 56573, 55349, 56574, 55349, + 56575, 55349, 56576, 55349, 56577, 55349, 56578, 55349, + 56579, 55349, 56580, 55349, 56581, 55349, 56583, 55349, + 56584, 55349, 56585, 55349, 56586, 55349, 56589, 55349, + 56590, 55349, 56591, 55349, 56592, 55349, 56593, 55349, + 56594, 55349, 56595, 55349, 56596, 55349, 56598, 55349, + 56599, 55349, 56600, 55349, 56601, 55349, 56602, 55349, + 56603, 55349, 56604, 55349, 56606, 55349, 56607, 55349, + 56608, 55349, 56609, 55349, 56610, 55349, 56611, 55349, + 56612, 55349, 56613, 55349, 56614, 55349, 56615, 55349, + 56616, 55349, 56617, 55349, 56618, 55349, 56619, 55349, + 56620, 55349, 56621, 55349, 56622, 55349, 56623, 55349, + 56624, 55349, 56625, 55349, 56626, 55349, 56627, 55349, + 56628, 55349, 56629, 55349, 56630, 55349, 56631, 55349, + 56632, 55349, 56633, 55349, 56635, 55349, 56636, 55349, + 56637, 55349, 56638, 55349, 56640, 55349, 56641, 55349, + 56642, 55349, 56643, 55349, 56644, 55349, 56646, 55349, + 56650, 55349, 56651, 55349, 56652, 55349, 56653, 55349, + 56654, 55349, 56655, 55349, 56656, 55349, 56658, 55349, + 56659, 55349, 56660, 55349, 56661, 55349, 56662, 55349, + 56663, 55349, 56664, 55349, 56665, 55349, 56666, 55349, + 56667, 55349, 56668, 55349, 56669, 55349, 56670, 55349, + 56671, 55349, 56672, 55349, 56673, 55349, 56674, 55349, + 56675, 55349, 56676, 55349, 56677, 55349, 56678, 55349, + 56679, 55349, 56680, 55349, 56681, 55349, 56682, 55349, + 56683, 55349, 56684, 55349, 56685, 55349, 56686, 55349, + 56687, 55349, 56688, 55349, 56689, 55349, 56690, 55349, + 56691, 55349, 56692, 55349, 56693, 55349, 56694, 55349, + 56695, 55349, 56696, 55349, 56697, 55349, 56698, 55349, + 56699, 55349, 56700, 55349, 56701, 55349, 56702, 55349, + 56703, 55349, 56704, 55349, 56705, 55349, 56706, 55349, + 56707, 55349, 56708, 55349, 56709, 55349, 56710, 55349, + 56711, 55349, 56712, 55349, 56713, 55349, 56714, 55349, + 56715, 55349, 56716, 55349, 56717, 55349, 56718, 55349, + 56719, 55349, 56720, 55349, 56721, 55349, 56722, 55349, + 56723, 55349, 56724, 55349, 56725, 55349, 56726, 55349, + 56727, 55349, 56728, 55349, 56729, 55349, 56730, 55349, + 56731, 55349, 56732, 55349, 56733, 55349, 56734, 55349, + 56735, 55349, 56736, 55349, 56737, 55349, 56738, 55349, + 56739, 55349, 56740, 55349, 56741, 55349, 56742, 55349, + 56743, 55349, 56744, 55349, 56745, 55349, 56746, 55349, + 56747, 55349, 56748, 55349, 56749, 55349, 56750, 55349, + 56751, 55349, 56752, 55349, 56753, 55349, 56754, 55349, + 56755, 55349, 56756, 55349, 56757, 55349, 56758, 55349, + 56759, 55349, 56760, 55349, 56761, 55349, 56762, 55349, + 56763, 55349, 56764, 55349, 56765, 55349, 56766, 55349, + 56767, 55349, 56768, 55349, 56769, 55349, 56770, 55349, + 56771, 55349, 56772, 55349, 56773, 55349, 56774, 55349, + 56775, 55349, 56776, 55349, 56777, 55349, 56778, 55349, + 56779, 55349, 56780, 55349, 56781, 55349, 56782, 55349, + 56783, 55349, 56784, 55349, 56785, 55349, 56786, 55349, + 56787, 55349, 56788, 55349, 56789, 55349, 56790, 55349, + 56791, 55349, 56792, 55349, 56793, 55349, 56794, 55349, + 56795, 55349, 56796, 55349, 56797, 55349, 56798, 55349, + 56799, 55349, 56800, 55349, 56801, 55349, 56802, 55349, + 56803, 55349, 56804, 55349, 56805, 55349, 56806, 55349, + 56807, 55349, 56808, 55349, 56809, 55349, 56810, 55349, + 56811, 55349, 56812, 55349, 56813, 55349, 56814, 55349, + 56815, 55349, 56816, 55349, 56817, 55349, 56818, 55349, + 56819, 55349, 56820, 55349, 56821, 55349, 56822, 55349, + 56823, 55349, 56824, 55349, 56825, 55349, 56826, 55349, + 56827, 55349, 56828, 55349, 56829, 55349, 56830, 55349, + 56831, 55349, 56832, 55349, 56833, 55349, 56834, 55349, + 56835, 55349, 56836, 55349, 56837, 55349, 56838, 55349, + 56839, 55349, 56840, 55349, 56841, 55349, 56842, 55349, + 56843, 55349, 56844, 55349, 56845, 55349, 56846, 55349, + 56847, 55349, 56848, 55349, 56849, 55349, 56850, 55349, + 56851, 55349, 56852, 55349, 56853, 55349, 56854, 55349, + 56855, 55349, 56856, 55349, 56857, 55349, 56858, 55349, + 56859, 55349, 56860, 55349, 56861, 55349, 56862, 55349, + 56863, 55349, 56864, 55349, 56865, 55349, 56866, 55349, + 56867, 55349, 56868, 55349, 56869, 55349, 56870, 55349, + 56871, 55349, 56872, 55349, 56873, 55349, 56874, 55349, + 56875, 55349, 56876, 55349, 56877, 55349, 56878, 55349, + 56879, 55349, 56880, 55349, 56881, 55349, 56882, 55349, + 56883, 55349, 56884, 55349, 56885, 55349, 56886, 55349, + 56887, 55349, 56888, 55349, 56889, 55349, 56890, 55349, + 56891, 55349, 56892, 55349, 56893, 55349, 56894, 55349, + 56895, 55349, 56896, 55349, 56897, 55349, 56898, 55349, + 56899, 55349, 56900, 55349, 56901, 55349, 56902, 55349, + 56903, 55349, 56904, 55349, 56905, 55349, 56906, 55349, + 56907, 55349, 56908, 55349, 56909, 55349, 56910, 55349, + 56911, 55349, 56912, 55349, 56913, 55349, 56914, 55349, + 56915, 55349, 56916, 55349, 56917, 55349, 56918, 55349, + 56919, 55349, 56920, 55349, 56921, 55349, 56922, 55349, + 56923, 55349, 56924, 55349, 56925, 55349, 56926, 55349, + 56927, 55349, 56928, 55349, 56929, 55349, 56930, 55349, + 56931, 55349, 56932, 55349, 56933, 55349, 56934, 55349, + 56935, 55349, 56936, 55349, 56937, 55349, 56938, 55349, + 56939, 55349, 56940, 55349, 56941, 55349, 56942, 55349, + 56943, 55349, 56944, 55349, 56945, 55349, 56946, 55349, + 56947, 55349, 56948, 55349, 56949, 55349, 56950, 55349, + 56951, 55349, 56952, 55349, 56953, 55349, 56954, 55349, + 56955, 55349, 56956, 55349, 56957, 55349, 56958, 55349, + 56959, 55349, 56960, 55349, 56961, 55349, 56962, 55349, + 56963, 55349, 56964, 55349, 56965, 55349, 56966, 55349, + 56967, 55349, 56968, 55349, 56969, 55349, 56970, 55349, + 56971, 55349, 56972, 55349, 56973, 55349, 56974, 55349, + 56975, 55349, 56976, 55349, 56977, 55349, 56978, 55349, + 56979, 55349, 56980, 55349, 56981, 55349, 56982, 55349, + 56983, 55349, 56984, 55349, 56985, 55349, 56986, 55349, + 56987, 55349, 56988, 55349, 56989, 55349, 56990, 55349, + 56991, 55349, 56992, 55349, 56993, 55349, 56994, 55349, + 56995, 55349, 56996, 55349, 56997, 55349, 57000, 55349, + 57001, 55349, 57002, 55349, 57003, 55349, 57004, 55349, + 57005, 55349, 57006, 55349, 57007, 55349, 57008, 55349, + 57009, 55349, 57010, 55349, 57011, 55349, 57012, 55349, + 57013, 55349, 57014, 55349, 57015, 55349, 57016, 55349, + 57017, 55349, 57018, 55349, 57019, 55349, 57020, 55349, + 57021, 55349, 57022, 55349, 57023, 55349, 57024, 55349, + 57026, 55349, 57027, 55349, 57028, 55349, 57029, 55349, + 57030, 55349, 57031, 55349, 57032, 55349, 57033, 55349, + 57034, 55349, 57035, 55349, 57036, 55349, 57037, 55349, + 57038, 55349, 57039, 55349, 57040, 55349, 57041, 55349, + 57042, 55349, 57043, 55349, 57044, 55349, 57045, 55349, + 57046, 55349, 57047, 55349, 57048, 55349, 57049, 55349, + 57050, 55349, 57052, 55349, 57053, 55349, 57054, 55349, + 57055, 55349, 57056, 55349, 57057, 55349, 57058, 55349, + 57059, 55349, 57060, 55349, 57061, 55349, 57062, 55349, + 57063, 55349, 57064, 55349, 57065, 55349, 57066, 55349, + 57067, 55349, 57068, 55349, 57069, 55349, 57070, 55349, + 57071, 55349, 57072, 55349, 57073, 55349, 57074, 55349, + 57075, 55349, 57076, 55349, 57077, 55349, 57078, 55349, + 57079, 55349, 57080, 55349, 57081, 55349, 57082, 55349, + 57084, 55349, 57085, 55349, 57086, 55349, 57087, 55349, + 57088, 55349, 57089, 55349, 57090, 55349, 57091, 55349, + 57092, 55349, 57093, 55349, 57094, 55349, 57095, 55349, + 57096, 55349, 57097, 55349, 57098, 55349, 57099, 55349, + 57100, 55349, 57101, 55349, 57102, 55349, 57103, 55349, + 57104, 55349, 57105, 55349, 57106, 55349, 57107, 55349, + 57108, 55349, 57110, 55349, 57111, 55349, 57112, 55349, + 57113, 55349, 57114, 55349, 57115, 55349, 57116, 55349, + 57117, 55349, 57118, 55349, 57119, 55349, 57120, 55349, + 57121, 55349, 57122, 55349, 57123, 55349, 57124, 55349, + 57125, 55349, 57126, 55349, 57127, 55349, 57128, 55349, + 57129, 55349, 57130, 55349, 57131, 55349, 57132, 55349, + 57133, 55349, 57134, 55349, 57135, 55349, 57136, 55349, + 57137, 55349, 57138, 55349, 57139, 55349, 57140, 55349, + 57142, 55349, 57143, 55349, 57144, 55349, 57145, 55349, + 57146, 55349, 57147, 55349, 57148, 55349, 57149, 55349, + 57150, 55349, 57151, 55349, 57152, 55349, 57153, 55349, + 57154, 55349, 57155, 55349, 57156, 55349, 57157, 55349, + 57158, 55349, 57159, 55349, 57160, 55349, 57161, 55349, + 57162, 55349, 57163, 55349, 57164, 55349, 57165, 55349, + 57166, 55349, 57168, 55349, 57169, 55349, 57170, 55349, + 57171, 55349, 57172, 55349, 57173, 55349, 57174, 55349, + 57175, 55349, 57176, 55349, 57177, 55349, 57178, 55349, + 57179, 55349, 57180, 55349, 57181, 55349, 57182, 55349, + 57183, 55349, 57184, 55349, 57185, 55349, 57186, 55349, + 57187, 55349, 57188, 55349, 57189, 55349, 57190, 55349, + 57191, 55349, 57192, 55349, 57193, 55349, 57194, 55349, + 57195, 55349, 57196, 55349, 57197, 55349, 57198, 55349, + 57200, 55349, 57201, 55349, 57202, 55349, 57203, 55349, + 57204, 55349, 57205, 55349, 57206, 55349, 57207, 55349, + 57208, 55349, 57209, 55349, 57210, 55349, 57211, 55349, + 57212, 55349, 57213, 55349, 57214, 55349, 57215, 55349, + 57216, 55349, 57217, 55349, 57218, 55349, 57219, 55349, + 57220, 55349, 57221, 55349, 57222, 55349, 57223, 55349, + 57224, 55349, 57226, 55349, 57227, 55349, 57228, 55349, + 57229, 55349, 57230, 55349, 57231, 55349, 57232, 55349, + 57233, 55349, 57234, 55349, 57235, 55349, 57236, 55349, + 57237, 55349, 57238, 55349, 57239, 55349, 57240, 55349, + 57241, 55349, 57242, 55349, 57243, 55349, 57244, 55349, + 57245, 55349, 57246, 55349, 57247, 55349, 57248, 55349, + 57249, 55349, 57250, 55349, 57251, 55349, 57252, 55349, + 57253, 55349, 57254, 55349, 57255, 55349, 57256, 55349, + 57258, 55349, 57259, 55349, 57260, 55349, 57261, 55349, + 57262, 55349, 57263, 55349, 57264, 55349, 57265, 55349, + 57266, 55349, 57267, 55349, 57268, 55349, 57269, 55349, + 57270, 55349, 57271, 55349, 57272, 55349, 57273, 55349, + 57274, 55349, 57275, 55349, 57276, 55349, 57277, 55349, + 57278, 55349, 57279, 55349, 57280, 55349, 57281, 55349, + 57282, 55349, 57284, 55349, 57285, 55349, 57286, 55349, + 57287, 55349, 57288, 55349, 57289, 55349, 57290, 55349, + 57291, 55351, 57088, 55351, 57089, 55351, 57090, 55351, + 57091, 55351, 57095, 55351, 57097, 55351, 57099, 55351, + 57100, 55351, 57101, 55351, 57102, 55351, 57103, 55351, + 57104, 55351, 57105, 55351, 57106, 55351, 57107, 55351, + 57108, 55351, 57109, 55351, 57110, 55351, 57111, 55351, + 57112, 55351, 57113, 55351, 57114, 55351, 57115, 55351, + 57116, 55351, 57117, 55351, 57125, 55351, 57126, 55351, + 57127, 55351, 57128, 55351, 57129, 55351, 57130, 55352, + 56368, 55352, 56369, 55352, 56370, 55352, 56371, 55352, + 56372, 55352, 56373, 55352, 56374, 55352, 56375, 55352, + 56376, 55352, 56377, 55352, 56378, 55352, 56379, 55352, + 56380, 55352, 56381, 55352, 56382, 55352, 56383, 55352, + 56384, 55352, 56385, 55352, 56386, 55352, 56387, 55352, + 56388, 55352, 56389, 55352, 56390, 55352, 56391, 55352, + 56392, 55352, 56393, 55352, 56394, 55352, 56395, 55352, + 56396, 55352, 56397, 55352, 56398, 55352, 56399, 55352, + 56400, 55352, 56401, 55352, 56402, 55352, 56403, 55352, + 56404, 55352, 56405, 55352, 56406, 55352, 56407, 55352, + 56408, 55352, 56409, 55352, 56410, 55352, 56411, 55352, + 56412, 55352, 56413, 55352, 56414, 55352, 56415, 55352, + 56416, 55352, 56417, 55352, 56418, 55352, 56419, 55352, + 56420, 55352, 56421, 55352, 56422, 55352, 56423, 55352, + 56424, 55352, 56425, 55352, 56426, 55352, 56427, 55352, + 56428, 55352, 56429, 55354, 56576, 55354, 56577, 55354, + 56578, 55354, 56579, 55354, 56580, 55354, 56581, 55354, + 56582, 55354, 56583, 55354, 56584, 55354, 56585, 55354, + 56586, 55354, 56587, 55354, 56588, 55354, 56589, 55354, + 56590, 55354, 56591, 55354, 56592, 55354, 56593, 55354, + 56594, 55354, 56595, 55354, 56596, 55354, 56597, 55354, + 56598, 55354, 56599, 55354, 56600, 55354, 56601, 55354, + 56602, 55354, 56603, 55354, 56604, 55354, 56605, 55354, + 56606, 55354, 56607, 55354, 56608, 55354, 56609, 55356, + 56624, 55356, 56625, 55356, 56626, 55356, 56627, 55356, + 56628, 55356, 56629, 55356, 56630, 55356, 56631, 55356, + 56632, 55356, 56633, 55356, 56634, 55356, 56635, 55356, + 56636, 55356, 56637, 55356, 56638, 55356, 56639, 55356, + 56640, 55356, 56641, 55356, 56642, 55356, 56643, 55356, + 56644, 55356, 56645, 55356, 56646, 55356, 56647, 55356, + 56648, 55356, 56649, 55356, 56656, 55356, 56657, 55356, + 56658, 55356, 56659, 55356, 56660, 55356, 56661, 55356, + 56662, 55356, 56663, 55356, 56664, 55356, 56665, 55356, + 56666, 55356, 56667, 55356, 56668, 55356, 56669, 55356, + 56670, 55356, 56671, 55356, 56672, 55356, 56673, 55356, + 56674, 55356, 56675, 55356, 56676, 55356, 56677, 55356, + 56678, 55356, 56679, 55356, 56680, 55356, 56681, 55356, + 56688, 55356, 56689, 55356, 56690, 55356, 56691, 55356, + 56692, 55356, 56693, 55356, 56694, 55356, 56695, 55356, + 56696, 55356, 56697, 55356, 56698, 55356, 56699, 55356, + 56700, 55356, 56701, 55356, 56702, 55356, 56703, 55356, + 56704, 55356, 56705, 55356, 56706, 55356, 56707, 55356, + 56708, 55356, 56709, 55356, 56710, 55356, 56711, 55356, + 56712, 55356, 56713, }; + +static const utf8proc_uint16_t utf8proc_stage1table[] = { + 0, 256, 512, 768, 1024, 1280, 1536, + 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, + 3840, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, + 7936, 8192, 8448, 8704, 8960, 9216, 9472, 9728, + 9984, 10240, 10496, 10752, 11008, 11264, 11520, 11776, + 12032, 12288, 12544, 12800, 13056, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13568, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13824, 13312, 13312, 13312, 14080, 5376, 14336, + 14592, 14848, 15104, 15360, 15616, 15872, 16128, 16384, + 16640, 16896, 17152, 17408, 15872, 16128, 16384, 16640, + 16896, 17152, 17408, 15872, 16128, 16384, 16640, 16896, + 17152, 17408, 15872, 16128, 16384, 16640, 16896, 17152, + 17408, 15872, 16128, 16384, 16640, 16896, 17152, 17408, + 15872, 16128, 16384, 16640, 16896, 17152, 17408, 15872, + 17664, 17920, 17920, 17920, 17920, 17920, 17920, 17920, + 17920, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18432, 18688, 18944, 19200, 19456, 19712, + 19968, 20224, 20480, 20736, 20992, 21248, 21504, 5376, + 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, + 23808, 24064, 24320, 24576, 24832, 25088, 25344, 25600, + 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, + 27904, 5376, 5376, 5376, 28160, 28416, 28672, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 29184, 5376, 5376, 5376, 5376, 29440, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 5376, 5376, 29696, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 5376, 5376, 29952, 30208, 28928, 28928, 30464, + 30720, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 30976, 13312, 13312, 13312, 13312, 31232, 31488, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 31744, 13312, 32000, 32256, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 32512, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 32768, 33024, 33280, 33536, 33792, 34048, 34304, 34560, + 34816, 10240, 10240, 35072, 28928, 28928, 28928, 28928, + 35328, 35584, 35840, 36096, 28928, 36352, 28928, 28928, + 36608, 36864, 37120, 28928, 28928, 37376, 37632, 37888, + 28928, 38144, 38400, 38656, 38912, 39168, 39424, 39680, + 39936, 40192, 40448, 40704, 40960, 28928, 28928, 28928, + 28928, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 41216, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 41472, 41728, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 41984, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 42240, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 42496, 42752, 43008, 28928, 28928, 28928, 28928, + 28928, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 43264, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 13312, 13312, 13312, 13312, + 13312, 13312, 13312, 13312, 43520, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 43776, 44032, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 28928, 28928, 28928, 28928, 28928, 28928, 28928, + 28928, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 44288, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 18176, 18176, 18176, 18176, 18176, 18176, 18176, 18176, + 44288, }; + +static const utf8proc_uint16_t utf8proc_stage2table[] = { + 1, 2, 2, 2, 2, 2, 2, + 2, 2, 3, 4, 3, 5, 6, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 7, 7, 7, + 3, 8, 9, 9, 10, 11, 10, 9, + 9, 12, 13, 9, 14, 15, 16, 15, + 15, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 15, 9, 18, 19, 20, + 9, 9, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 12, 9, 13, 47, + 48, 47, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 12, 75, 13, 75, + 2, 2, 2, 2, 2, 2, 7, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 76, 9, 11, 11, 11, 11, 77, + 9, 78, 79, 80, 81, 75, 82, 79, + 83, 84, 85, 86, 87, 88, 89, 9, + 9, 90, 91, 92, 93, 94, 95, 96, + 9, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 75, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, + 75, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 331, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, + 350, 346, 346, 346, 346, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, 430, 431, 432, 433, + 434, 435, 436, 437, 438, 439, 440, 441, + 442, 443, 444, 445, 446, 447, 448, 449, + 450, 451, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 496, 497, + 498, 499, 500, 501, 502, 503, 504, 505, + 506, 507, 508, 509, 510, 511, 512, 513, + 514, 515, 516, 517, 518, 519, 520, 521, + 522, 523, 524, 525, 526, 527, 528, 529, + 530, 531, 532, 533, 534, 535, 536, 537, + 538, 539, 540, 541, 542, 543, 544, 545, + 546, 547, 548, 549, 550, 551, 552, 553, + 554, 555, 556, 557, 558, 346, 559, 560, + 561, 562, 563, 564, 565, 566, 567, 568, + 569, 570, 571, 572, 573, 574, 575, 576, + 577, 578, 579, 580, 581, 582, 583, 584, + 585, 586, 587, 588, 589, 590, 591, 592, + 593, 594, 595, 595, 596, 596, 596, 596, + 596, 597, 598, 47, 47, 47, 47, 595, + 595, 595, 595, 595, 595, 595, 595, 595, + 595, 596, 596, 47, 47, 47, 47, 47, + 47, 599, 600, 601, 602, 603, 604, 47, + 47, 605, 606, 607, 608, 609, 47, 47, + 47, 47, 47, 47, 47, 595, 47, 596, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 610, 611, 612, 613, 614, 615, 616, + 617, 618, 619, 620, 621, 622, 615, 615, + 623, 615, 624, 615, 625, 626, 627, 628, + 628, 628, 628, 627, 629, 628, 628, 628, + 628, 628, 630, 630, 631, 632, 633, 634, + 635, 636, 628, 628, 628, 628, 637, 638, + 628, 639, 640, 628, 628, 641, 641, 641, + 641, 642, 628, 628, 628, 628, 615, 615, + 615, 643, 644, 645, 646, 647, 648, 615, + 628, 628, 628, 615, 615, 615, 628, 628, + 649, 615, 615, 615, 628, 628, 628, 628, + 615, 627, 628, 628, 615, 650, 651, 651, + 650, 651, 651, 650, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, + 615, 652, 653, 654, 655, 656, 47, 657, + 658, 0, 0, 659, 660, 661, 662, 663, + 664, 0, 0, 0, 0, 88, 665, 666, + 667, 668, 669, 670, 0, 671, 0, 672, + 673, 674, 675, 676, 677, 678, 679, 680, + 681, 682, 683, 684, 685, 686, 687, 688, + 689, 690, 691, 0, 692, 693, 694, 695, + 696, 697, 698, 699, 700, 701, 702, 703, + 704, 705, 706, 707, 708, 709, 710, 711, + 712, 713, 714, 715, 716, 717, 718, 719, + 720, 721, 722, 723, 724, 725, 726, 727, + 728, 729, 730, 731, 732, 733, 734, 735, + 736, 737, 738, 739, 740, 741, 742, 743, + 744, 745, 746, 747, 748, 749, 750, 751, + 752, 753, 754, 755, 756, 757, 758, 759, + 760, 761, 762, 763, 764, 765, 766, 767, + 768, 769, 770, 771, 772, 773, 774, 75, + 775, 776, 777, 778, 779, 780, 781, 782, + 783, 784, 785, 786, 787, 788, 789, 790, + 791, 792, 793, 794, 795, 796, 797, 798, + 799, 800, 801, 802, 803, 804, 805, 806, + 807, 808, 809, 810, 811, 812, 813, 814, + 815, 816, 817, 818, 819, 820, 821, 822, + 823, 824, 825, 826, 827, 828, 829, 830, + 831, 832, 833, 834, 835, 836, 837, 838, + 839, 840, 841, 842, 843, 844, 845, 846, + 847, 848, 849, 850, 851, 852, 853, 854, + 855, 856, 857, 858, 859, 860, 861, 862, + 863, 864, 865, 866, 867, 868, 869, 870, + 871, 872, 873, 874, 875, 876, 877, 878, + 879, 880, 881, 882, 883, 884, 885, 886, + 887, 888, 889, 890, 891, 892, 893, 894, + 895, 896, 897, 898, 899, 900, 901, 902, + 903, 904, 905, 906, 907, 908, 909, 910, + 911, 912, 913, 914, 615, 615, 615, 615, + 615, 915, 915, 916, 917, 918, 919, 920, + 921, 922, 923, 924, 925, 926, 927, 928, + 929, 930, 931, 932, 933, 934, 935, 936, + 937, 938, 939, 940, 941, 942, 943, 944, + 945, 946, 947, 948, 949, 950, 951, 952, + 953, 954, 955, 956, 957, 958, 959, 960, + 961, 962, 963, 964, 965, 966, 967, 968, + 969, 970, 971, 972, 973, 974, 975, 976, + 977, 978, 979, 980, 981, 982, 983, 984, + 985, 986, 987, 988, 989, 990, 991, 992, + 993, 994, 995, 996, 997, 998, 999, 1000, + 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, + 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, + 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, + 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, + 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, + 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, + 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, + 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, + 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, + 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, + 1081, 0, 1082, 1083, 1084, 1085, 1086, 1087, + 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, + 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, + 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, + 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, + 0, 0, 596, 1120, 1120, 1120, 1120, 1120, + 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, + 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, + 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, + 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, + 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, + 1160, 1161, 1120, 1162, 0, 0, 77, 77, + 11, 0, 628, 615, 615, 615, 615, 628, + 615, 615, 615, 1163, 628, 615, 615, 615, + 615, 615, 615, 628, 628, 628, 628, 628, + 628, 615, 615, 628, 615, 615, 1163, 1164, + 615, 1165, 1166, 1167, 1168, 1169, 1170, 1171, + 1172, 1173, 1174, 1174, 1175, 1176, 1177, 1178, + 1179, 1180, 1181, 1182, 1180, 615, 628, 1180, + 1173, 0, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 0, 0, 0, 0, + 1183, 1183, 1183, 1183, 1180, 1180, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1184, 1184, 1184, 1184, 1184, 1184, 75, + 75, 1185, 10, 10, 1186, 15, 1187, 77, + 77, 615, 615, 615, 615, 615, 615, 615, + 615, 1188, 1189, 1190, 1187, 1191, 1187, 1187, + 1187, 1192, 1192, 1193, 1194, 1195, 1196, 1197, + 1198, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1199, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1200, 1192, 1201, 1202, 1203, 1204, 1188, + 1189, 1190, 1205, 1206, 1207, 1208, 1209, 628, + 615, 615, 615, 615, 615, 628, 615, 615, + 628, 1210, 1210, 1210, 1210, 1210, 1210, 1210, + 1210, 1210, 1210, 10, 1211, 1211, 1187, 1192, + 1192, 1212, 1192, 1192, 1192, 1192, 1213, 1214, + 1215, 1216, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1217, 1218, 1219, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1220, 1221, 1187, 1222, 615, + 615, 615, 615, 615, 615, 615, 1184, 77, + 615, 615, 615, 615, 628, 615, 1199, 1199, + 615, 615, 77, 628, 615, 615, 628, 1192, + 1192, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 1192, 1192, 1192, 1223, 1223, + 1192, 1187, 1187, 1187, 1187, 1187, 1187, 1187, + 1187, 1187, 1187, 1187, 1187, 1187, 1187, 0, + 1224, 1192, 1225, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 615, 628, 615, 615, 628, 615, 615, + 628, 628, 628, 615, 628, 628, 615, 628, + 615, 615, 615, 628, 615, 628, 615, 628, + 615, 628, 615, 615, 0, 0, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1192, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1227, 1227, 1227, 1227, 1227, 1227, 1227, + 1227, 1227, 1227, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 615, 615, 615, 615, + 615, 615, 615, 628, 615, 1228, 1228, 77, + 9, 9, 9, 1228, 0, 0, 628, 1229, + 1229, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 615, + 615, 615, 615, 1228, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 1228, 615, 615, + 615, 1228, 615, 615, 615, 615, 615, 0, + 0, 1180, 1180, 1180, 1180, 1180, 1180, 1180, + 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 628, 628, 628, 0, 0, 1180, + 0, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 0, 0, 0, 0, + 0, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1230, 1192, 1192, 1192, 1192, 1192, 1192, + 0, 1184, 1184, 0, 0, 0, 0, 0, + 0, 615, 628, 628, 628, 615, 615, 615, + 615, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1199, 615, 615, 615, 615, 615, + 628, 628, 628, 628, 628, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 1184, 628, 615, 615, 628, + 615, 615, 628, 615, 615, 615, 628, 628, + 628, 1202, 1203, 1204, 615, 615, 615, 628, + 615, 615, 628, 628, 615, 615, 615, 615, + 615, 1226, 1226, 1226, 1231, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 1232, 1233, 346, 346, 346, 346, 346, + 346, 1234, 1235, 346, 1236, 1237, 346, 346, + 346, 346, 346, 1226, 1231, 1238, 346, 1231, + 1231, 1231, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1231, 1231, 1231, 1231, 1239, 1231, + 1231, 346, 615, 628, 615, 615, 1226, 1226, + 1226, 1240, 1241, 1242, 1243, 1244, 1245, 1246, + 1247, 346, 346, 1226, 1226, 1120, 1120, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1120, 596, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1226, 1231, 1231, 0, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 0, + 346, 346, 0, 0, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 0, 0, 0, 346, + 346, 346, 346, 0, 0, 1249, 346, 1250, + 1231, 1231, 1226, 1226, 1226, 1226, 0, 0, + 1251, 1231, 0, 0, 1252, 1253, 1239, 346, + 0, 0, 0, 0, 0, 0, 0, 0, + 1254, 0, 0, 0, 0, 1255, 1256, 0, + 1257, 346, 346, 1226, 1226, 0, 0, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 346, 346, 11, 11, 1258, 1258, 1258, + 1258, 1258, 1258, 914, 11, 346, 1120, 615, + 0, 0, 1226, 1226, 1231, 0, 346, 346, + 346, 346, 346, 346, 0, 0, 0, 0, + 346, 346, 0, 0, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 1259, 0, 346, 1260, + 0, 346, 346, 0, 0, 1249, 0, 1231, + 1231, 1231, 1226, 1226, 0, 0, 0, 0, + 1226, 1226, 0, 0, 1226, 1226, 1239, 0, + 0, 0, 1226, 0, 0, 0, 0, 0, + 0, 0, 1261, 1262, 1263, 346, 0, 1264, + 0, 0, 0, 0, 0, 0, 0, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1226, 1226, 346, 346, 346, 1226, 1120, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1226, 1226, 1231, 0, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 0, + 346, 346, 346, 0, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 0, 346, 346, + 346, 346, 346, 0, 0, 1249, 346, 1231, + 1231, 1231, 1226, 1226, 1226, 1226, 1226, 0, + 1226, 1226, 1231, 0, 1231, 1231, 1239, 0, + 0, 346, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 1226, 1226, 0, 0, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1120, 11, 0, 0, 0, 0, 0, + 0, 0, 346, 1226, 1226, 1226, 1226, 1226, + 1226, 0, 1226, 1231, 1231, 0, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 0, + 346, 346, 0, 0, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 0, 346, 346, + 346, 346, 346, 0, 0, 1249, 346, 1265, + 1226, 1231, 1226, 1226, 1226, 1226, 0, 0, + 1266, 1267, 0, 0, 1268, 1269, 1239, 0, + 0, 0, 0, 0, 0, 0, 1226, 1270, + 1271, 0, 0, 0, 0, 1272, 1273, 0, + 346, 346, 346, 1226, 1226, 0, 0, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 914, 346, 1258, 1258, 1258, 1258, 1258, + 1258, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1226, 346, 0, 346, 346, + 346, 346, 346, 346, 0, 0, 0, 346, + 346, 346, 0, 1274, 346, 1275, 346, 0, + 0, 0, 346, 346, 0, 346, 0, 346, + 346, 0, 0, 0, 346, 346, 0, 0, + 0, 346, 346, 346, 0, 0, 0, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 0, 0, 0, 0, 1276, + 1231, 1226, 1231, 1231, 0, 0, 0, 1277, + 1278, 1231, 0, 1279, 1280, 1281, 1239, 0, + 0, 346, 0, 0, 0, 0, 0, 0, + 1282, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1258, 1258, 1258, 77, 77, 77, 77, + 77, 77, 11, 77, 0, 0, 0, 0, + 0, 1226, 1231, 1231, 1231, 1226, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 0, 0, 1249, 346, 1226, + 1226, 1226, 1231, 1231, 1231, 1231, 0, 1283, + 1226, 1284, 0, 1226, 1226, 1226, 1239, 0, + 0, 0, 0, 0, 0, 0, 1285, 1286, + 0, 346, 346, 346, 0, 0, 346, 0, + 0, 346, 346, 1226, 1226, 0, 0, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 0, 0, 0, 0, 0, 0, 0, + 1120, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 914, 346, 1226, 1231, 1231, 1120, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 0, 346, 346, + 346, 346, 346, 0, 0, 1249, 346, 1231, + 1288, 1289, 1231, 1290, 1231, 1231, 0, 1291, + 1292, 1293, 0, 1294, 1295, 1226, 1239, 0, + 0, 0, 0, 0, 0, 0, 1296, 1297, + 0, 0, 0, 0, 0, 0, 346, 346, + 0, 346, 346, 1226, 1226, 0, 0, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 0, 346, 346, 1231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1226, 1226, 1231, 1231, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1239, 1239, 346, 1298, + 1231, 1231, 1226, 1226, 1226, 1226, 0, 1299, + 1300, 1231, 0, 1301, 1302, 1303, 1239, 1304, + 914, 0, 0, 0, 0, 346, 346, 346, + 1305, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 346, 346, 346, 1226, 1226, 0, 0, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 914, 346, 346, 346, 346, 346, + 346, 0, 1226, 1231, 1231, 0, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 0, 0, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 0, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 0, 346, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 0, 0, 1306, 0, 0, 0, 0, + 1307, 1231, 1231, 1226, 1226, 1226, 0, 1226, + 0, 1231, 1308, 1309, 1231, 1310, 1311, 1312, + 1313, 0, 0, 0, 0, 0, 0, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 0, 0, 1231, 1231, 1120, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1226, 346, 1314, 1226, 1226, 1226, + 1226, 1315, 1315, 1239, 0, 0, 0, 0, + 11, 346, 346, 346, 346, 346, 346, 596, + 1226, 1316, 1316, 1316, 1316, 1226, 1226, 1226, + 1120, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1120, 1120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 346, 346, 0, 346, 0, 346, + 346, 346, 346, 346, 0, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 0, 346, 0, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1226, 346, 1317, 1226, 1226, 1226, + 1226, 1318, 1318, 1239, 1226, 1226, 346, 0, + 0, 346, 346, 346, 346, 346, 0, 596, + 0, 1319, 1319, 1319, 1319, 1226, 1226, 1226, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 1320, 1321, 346, + 346, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 914, 914, 914, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1322, 1120, 1120, + 1120, 1120, 1120, 1120, 914, 1120, 914, 914, + 914, 628, 628, 914, 914, 914, 914, 914, + 914, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 914, 628, 914, + 628, 914, 1323, 12, 13, 12, 13, 1231, + 1231, 346, 346, 346, 1324, 346, 346, 346, + 346, 0, 346, 346, 346, 346, 1325, 346, + 346, 346, 346, 1326, 346, 346, 346, 346, + 1327, 346, 346, 346, 346, 1328, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1329, 346, 346, 346, 0, 0, + 0, 0, 1330, 1331, 1332, 1333, 1334, 1335, + 1336, 1337, 1338, 1331, 1331, 1331, 1331, 1226, + 1231, 1331, 1339, 615, 615, 1239, 1120, 615, + 615, 346, 346, 346, 346, 346, 1226, 1226, + 1226, 1226, 1226, 1226, 1340, 1226, 1226, 1226, + 1226, 0, 1226, 1226, 1226, 1226, 1341, 1226, + 1226, 1226, 1226, 1342, 1226, 1226, 1226, 1226, + 1343, 1226, 1226, 1226, 1226, 1344, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1345, 1226, 1226, 1226, 0, 914, + 914, 914, 914, 914, 914, 914, 914, 628, + 914, 914, 914, 914, 914, 914, 0, 914, + 914, 1120, 1120, 1120, 1120, 1120, 914, 914, + 914, 914, 1120, 1120, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 1346, 1347, + 346, 346, 346, 346, 1348, 1348, 1226, 1349, + 1226, 1226, 1231, 1226, 1226, 1226, 1226, 1226, + 1249, 1348, 1239, 1239, 1231, 1231, 1226, 1226, + 346, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1120, 1120, 1120, 1120, 1120, + 1120, 346, 346, 346, 346, 346, 346, 1231, + 1231, 1226, 1226, 346, 346, 346, 346, 1226, + 1226, 1226, 346, 1348, 1348, 1348, 346, 346, + 1348, 1348, 1348, 1348, 1348, 1348, 1348, 346, + 346, 346, 1226, 1226, 1226, 1226, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 1226, 1348, 1231, 1226, 1226, + 1348, 1348, 1348, 1348, 1348, 1348, 628, 346, + 1348, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1348, 1348, 1348, 1226, 914, + 914, 1350, 1351, 1352, 1353, 1354, 1355, 1356, + 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, + 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, + 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, + 1381, 1382, 1383, 1384, 1385, 1386, 1387, 0, + 1388, 0, 0, 0, 0, 0, 1389, 0, + 0, 1390, 1391, 1392, 1393, 1394, 1395, 1396, + 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, + 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, + 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, + 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, + 1429, 1430, 1431, 1432, 1120, 1433, 1434, 1435, + 1436, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1438, 1439, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 0, 346, 346, 346, 346, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 0, 346, 346, 346, 346, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 0, 0, 615, 615, + 615, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 0, 0, 0, 0, 0, + 0, 1442, 1443, 1444, 1445, 1446, 1447, 1448, + 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, + 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, + 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, + 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, + 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, + 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, + 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, + 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, + 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, + 1521, 1522, 1523, 1524, 1525, 1526, 1527, 0, + 0, 1528, 1529, 1530, 1531, 1532, 1533, 0, + 0, 1162, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 914, 1120, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 8, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 12, 13, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1120, 1120, 1120, 1534, + 1534, 1534, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 1226, 1226, 1239, 1535, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 1226, 1226, 1535, 1120, 1120, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 1226, 1226, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 346, + 346, 346, 0, 1226, 1226, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 649, 649, 1231, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1231, + 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1226, + 1231, 1231, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1239, 1226, 1120, 1120, 1120, + 596, 1120, 1120, 1120, 11, 346, 615, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 1162, + 9, 9, 9, 9, 649, 649, 649, 1536, + 649, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 596, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 1226, 1226, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1164, 346, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 1226, 1226, 1226, 1231, 1231, 1231, 1231, + 1226, 1226, 1231, 1231, 1231, 0, 0, 0, + 0, 1231, 1231, 1226, 1231, 1231, 1231, 1231, + 1231, 1231, 1163, 615, 628, 0, 0, 0, + 0, 77, 0, 0, 0, 9, 9, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 0, + 0, 346, 346, 346, 346, 346, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1258, 0, 0, 0, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 615, 628, 1231, 1231, 1226, 0, 0, 1120, + 1120, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 1231, 1226, + 1231, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 0, 1239, 1348, 1226, 1348, 1348, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1231, 1231, + 1231, 1231, 1231, 1231, 1226, 1226, 615, 615, + 615, 615, 615, 615, 615, 615, 0, 0, + 628, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 596, 1120, 1120, 1120, 1120, 1120, 1120, 0, + 0, 615, 615, 615, 615, 615, 628, 628, + 628, 628, 628, 628, 615, 615, 628, 915, + 628, 628, 615, 615, 628, 628, 615, 615, + 615, 615, 615, 628, 615, 615, 615, 615, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1226, 1226, 1226, 1226, 1231, 1537, 1538, + 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, + 346, 346, 1547, 1548, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 1249, 1549, 1226, + 1226, 1226, 1226, 1550, 1551, 1552, 1553, 1554, + 1555, 1556, 1557, 1558, 1559, 1535, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 615, 628, 615, 615, + 615, 615, 615, 615, 615, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 1120, 1120, + 0, 1226, 1226, 1231, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1231, 1226, 1226, 1226, 1226, 1231, + 1231, 1226, 1226, 1535, 1239, 1226, 1226, 346, + 346, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 1249, + 1231, 1226, 1226, 1231, 1231, 1231, 1226, 1231, + 1226, 1226, 1226, 1535, 1535, 0, 0, 0, + 0, 0, 0, 0, 0, 1120, 1120, 1120, + 1120, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 1231, 1231, 1231, + 1231, 1231, 1231, 1231, 1231, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1231, 1231, 1226, + 1249, 0, 0, 0, 1120, 1120, 1120, 1120, + 1120, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 346, 346, + 346, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 596, 596, 596, 596, 596, 596, 1120, + 1120, 1560, 1561, 1562, 1563, 1564, 1564, 1565, + 1566, 1567, 0, 0, 0, 0, 0, 0, + 0, 1568, 1569, 1570, 1571, 1572, 1573, 1574, + 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, + 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, + 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, + 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, + 1607, 1608, 1609, 1610, 0, 0, 1611, 1612, + 1613, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 0, 0, 0, 0, 0, 0, 0, + 0, 615, 615, 615, 1120, 641, 628, 628, + 628, 628, 628, 615, 615, 628, 628, 628, + 628, 615, 1231, 641, 641, 641, 641, 641, + 641, 641, 346, 346, 346, 346, 628, 346, + 346, 346, 346, 346, 346, 615, 346, 346, + 1231, 615, 615, 346, 0, 0, 0, 0, + 0, 1614, 1615, 1616, 1617, 1618, 1619, 1620, + 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, + 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, + 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, + 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, + 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, + 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, + 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, + 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, + 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, + 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, + 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, + 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, + 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, + 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, + 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, + 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, + 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, + 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, + 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, + 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, + 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, + 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, + 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, + 1805, 615, 615, 628, 615, 615, 615, 615, + 615, 615, 615, 628, 615, 615, 651, 1806, + 628, 630, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 627, + 1164, 1164, 628, 1807, 615, 650, 628, 615, + 628, 1808, 1809, 1810, 1811, 1812, 1813, 1814, + 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, + 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, + 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, + 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, + 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, + 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, + 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, + 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, + 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, + 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, + 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, + 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, + 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, + 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, + 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, + 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, + 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, + 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, + 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, + 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, + 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, + 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, + 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, + 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, + 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, + 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, + 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, + 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, + 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, + 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, + 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, + 2079, 2080, 2081, 2082, 2083, 2084, 2085, 0, + 0, 2086, 2087, 2088, 2089, 2090, 2091, 0, + 0, 2092, 2093, 2094, 2095, 2096, 2097, 2098, + 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, + 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, + 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, + 2123, 2124, 2125, 2126, 2127, 2128, 2129, 0, + 0, 2130, 2131, 2132, 2133, 2134, 2135, 0, + 0, 2136, 2137, 2138, 2139, 2140, 2141, 2142, + 2143, 0, 2144, 0, 2145, 0, 2146, 0, + 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, + 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, + 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, + 2171, 2172, 2173, 2174, 2175, 2176, 2177, 0, + 0, 2178, 2179, 2180, 2181, 2182, 2183, 2184, + 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, + 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, + 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, + 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, + 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, + 2225, 2226, 2227, 2228, 2229, 2230, 0, 2231, + 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, + 2240, 2241, 2242, 2243, 2244, 2245, 0, 2246, + 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, + 2255, 2256, 2257, 2258, 2259, 0, 0, 2260, + 2261, 2262, 2263, 2264, 2265, 0, 2266, 2267, + 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, + 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, + 2284, 0, 0, 2285, 2286, 2287, 0, 2288, + 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, + 0, 2297, 2298, 2299, 2299, 2299, 2299, 2299, + 2300, 2299, 2299, 2299, 1536, 2301, 2302, 2303, + 2304, 1162, 2305, 1162, 1162, 1162, 1162, 9, + 2306, 2307, 2308, 2309, 2307, 2307, 2308, 2309, + 2307, 9, 9, 9, 9, 2310, 2311, 2312, + 9, 2313, 2314, 2315, 2316, 2317, 2318, 2319, + 76, 10, 10, 10, 2320, 2321, 9, 2322, + 2323, 9, 81, 93, 9, 2324, 9, 2325, + 48, 48, 9, 9, 9, 2326, 12, 13, + 2327, 2328, 2329, 9, 9, 9, 9, 9, + 9, 9, 9, 75, 9, 48, 9, 9, + 2330, 9, 9, 9, 9, 9, 9, 9, + 2299, 1536, 1536, 1536, 1536, 1536, 0, 2331, + 2332, 2333, 2334, 1536, 1536, 1536, 1536, 1536, + 1536, 2335, 2336, 0, 0, 2337, 2338, 2339, + 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, + 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, + 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, + 0, 2364, 2365, 2366, 2367, 2368, 2369, 2370, + 2371, 2372, 2373, 2374, 2375, 2376, 0, 0, + 0, 11, 11, 11, 11, 11, 11, 11, + 11, 2377, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 615, 615, 641, 641, 615, 615, 615, + 615, 641, 641, 641, 615, 615, 915, 915, + 915, 915, 615, 915, 915, 915, 641, 641, + 615, 628, 615, 641, 641, 628, 628, 628, + 628, 615, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2378, 2379, 2380, 2381, 77, 2382, 2383, + 2384, 77, 2385, 2386, 2387, 2388, 2389, 2390, + 2391, 2392, 2393, 2394, 2395, 77, 2396, 2397, + 77, 75, 2398, 2399, 2400, 2401, 2402, 77, + 77, 2403, 2404, 2405, 77, 2406, 77, 2407, + 77, 2408, 77, 2409, 2410, 2411, 2412, 84, + 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, + 2421, 2422, 2423, 77, 2424, 2425, 2426, 2427, + 2428, 2429, 75, 75, 75, 75, 2430, 2431, + 2432, 2433, 2434, 77, 75, 77, 77, 2435, + 914, 2436, 2437, 2438, 2439, 2440, 2441, 2442, + 2443, 2444, 2445, 2446, 2447, 2448, 2449, 2450, + 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458, + 2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, + 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474, + 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482, + 2483, 1534, 1534, 1534, 2484, 2485, 1534, 1534, + 1534, 1534, 2486, 77, 77, 0, 0, 0, + 0, 2487, 75, 2488, 75, 2489, 79, 79, + 79, 79, 79, 2490, 2491, 77, 77, 77, + 77, 75, 77, 77, 75, 77, 77, 75, + 77, 77, 79, 79, 77, 77, 77, 2492, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 2493, 2494, + 2495, 2496, 77, 2497, 77, 2498, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 2499, 2499, 2500, 2501, 75, 75, + 75, 2502, 2503, 2499, 2504, 2505, 2499, 75, + 75, 75, 2499, 14, 85, 75, 2499, 2499, + 75, 75, 75, 2499, 2499, 2499, 2499, 75, + 2499, 2499, 2499, 2499, 2506, 2507, 2508, 2509, + 75, 75, 75, 75, 2499, 2510, 2511, 2499, + 2512, 2513, 2499, 2499, 2499, 75, 75, 75, + 75, 75, 2499, 75, 2499, 2514, 2499, 2499, + 2499, 2499, 2515, 2499, 2516, 2517, 2518, 2499, + 2519, 2520, 2521, 2499, 2499, 2499, 2522, 75, + 75, 75, 75, 2499, 2499, 2499, 2499, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 2499, 2523, 2524, 2525, 75, 2526, 2527, 2499, + 2499, 2499, 2499, 2499, 2499, 75, 2528, 2529, + 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, + 2538, 2539, 2540, 2541, 2542, 2543, 2544, 2499, + 2499, 2545, 2546, 2547, 2548, 2549, 2550, 2551, + 2552, 2553, 2554, 2499, 2499, 2499, 75, 75, + 2499, 2499, 2555, 2556, 75, 75, 75, 75, + 75, 2499, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 2557, 2499, 75, 75, 2499, + 2499, 2558, 2559, 2499, 2560, 2561, 2562, 2563, + 2564, 2499, 2499, 2565, 2566, 2567, 2568, 2499, + 2499, 2499, 75, 75, 75, 75, 75, 2499, + 2499, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 2499, 2499, 2499, 2499, 2499, 75, + 75, 2499, 2499, 75, 75, 75, 75, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2569, 2570, 2571, 2572, 2499, 2499, 2499, + 2499, 2499, 2499, 2573, 2574, 2575, 2576, 75, + 75, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 77, 77, 77, 77, 77, 77, 77, + 77, 12, 13, 12, 13, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 2577, 2577, 77, 77, 77, + 77, 2499, 2499, 77, 77, 77, 77, 77, + 77, 79, 2578, 2579, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 77, 75, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 79, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 914, 77, + 77, 77, 77, 77, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 79, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 75, 75, 75, + 75, 75, 75, 77, 77, 77, 77, 77, + 77, 77, 2577, 2577, 2577, 2577, 79, 79, + 79, 2577, 79, 79, 2577, 77, 77, 77, + 77, 79, 79, 79, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2580, 2581, 2582, 2583, 2584, 2585, 2586, + 2587, 2588, 2589, 2590, 2591, 2592, 2593, 2594, + 2595, 2596, 2597, 2598, 2599, 2600, 2601, 2602, + 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, + 2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, + 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, + 2627, 2628, 2629, 2630, 2631, 2632, 2633, 2634, + 2635, 2636, 2637, 2638, 2639, 2640, 2641, 2642, + 2643, 2644, 2645, 2646, 2647, 2648, 2649, 2650, + 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, + 2659, 2660, 2661, 2662, 2663, 2664, 2665, 2666, + 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, + 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, + 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, + 2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, + 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, + 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2714, + 2715, 2716, 2717, 2718, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 79, 79, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 79, + 75, 77, 77, 77, 77, 77, 77, 77, + 77, 79, 75, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 75, 75, 75, 2719, 2719, 2720, 2720, + 75, 79, 79, 79, 79, 79, 79, 77, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 77, 2577, 2577, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 2719, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 2577, 79, 79, 79, 79, 79, 79, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 79, 79, 79, 2577, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 2577, 79, 79, 79, 79, 79, + 79, 79, 79, 2577, 2577, 2721, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 2577, 2577, + 79, 79, 79, 79, 79, 2577, 2577, 79, + 79, 79, 79, 79, 79, 79, 79, 2577, + 79, 79, 79, 79, 79, 2577, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 2577, 79, 79, 79, 79, + 79, 79, 79, 2577, 2577, 79, 2577, 79, + 79, 79, 79, 2577, 79, 79, 2577, 79, + 79, 79, 79, 79, 79, 79, 2577, 77, + 77, 79, 79, 2577, 2577, 79, 79, 79, + 79, 79, 79, 79, 77, 79, 77, 79, + 77, 77, 77, 77, 77, 77, 79, 77, + 77, 77, 79, 77, 77, 77, 77, 77, + 77, 2577, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 79, 79, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 79, 77, 77, + 79, 77, 77, 77, 77, 2577, 77, 2577, + 77, 77, 77, 77, 2577, 2577, 2577, 77, + 2577, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 79, 79, 79, 79, + 79, 12, 13, 12, 13, 12, 13, 12, + 13, 12, 13, 12, 13, 12, 13, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 77, 2577, 2577, + 2577, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 79, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 2577, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 2577, 2499, 75, 75, 2499, 2499, 12, 13, + 75, 2499, 2499, 75, 2499, 2499, 2499, 75, + 75, 75, 75, 75, 2499, 2499, 2499, 2499, + 75, 75, 75, 75, 75, 2499, 2499, 2499, + 75, 75, 75, 2499, 2499, 2499, 2499, 12, + 13, 12, 13, 12, 13, 12, 13, 12, + 13, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 2719, 2719, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 12, 13, 12, 13, + 12, 13, 12, 13, 12, 13, 12, 13, + 12, 13, 12, 13, 12, 13, 12, 13, + 12, 13, 75, 75, 2499, 2499, 2499, 2499, + 2499, 2499, 75, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 75, 75, 75, 75, 75, 75, 75, + 75, 2499, 75, 75, 75, 75, 75, 75, + 75, 2499, 2499, 2499, 2499, 2499, 2499, 75, + 75, 75, 2499, 75, 75, 75, 75, 2499, + 2499, 2499, 2499, 2499, 75, 2499, 2499, 75, + 75, 12, 13, 12, 13, 2499, 75, 75, + 75, 75, 2499, 75, 2499, 2499, 2499, 75, + 75, 2499, 2499, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 2499, 2499, 2499, + 2499, 2499, 2499, 75, 75, 12, 13, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 2499, 2499, 2722, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 75, 2499, + 2499, 2499, 2499, 75, 75, 2499, 75, 2499, + 75, 75, 2499, 75, 2499, 2499, 2499, 2499, + 75, 75, 75, 75, 75, 2499, 2499, 75, + 75, 75, 75, 75, 75, 2499, 2499, 2499, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 2499, 2499, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 2499, 2499, 75, + 75, 75, 75, 2499, 2499, 2499, 2499, 75, + 2499, 2499, 75, 75, 2499, 2723, 2724, 2725, + 75, 75, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 75, 75, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 75, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, + 75, 75, 75, 75, 75, 2726, 2727, 2499, + 75, 75, 75, 2499, 2499, 2499, 2499, 2499, + 75, 75, 75, 75, 75, 2499, 2499, 2499, + 75, 75, 75, 75, 2499, 75, 75, 75, + 2499, 2499, 2499, 2499, 2499, 75, 2499, 75, + 75, 77, 77, 77, 77, 77, 79, 79, + 79, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 2577, 2577, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 77, 77, + 75, 75, 75, 75, 75, 75, 77, 77, + 77, 2577, 77, 77, 77, 77, 2577, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 0, 0, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 0, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 2728, + 77, 2729, 2730, 2731, 2732, 2733, 2734, 2735, + 2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, + 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, + 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, + 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, + 2768, 2769, 2770, 2771, 2772, 2773, 2774, 2775, + 2776, 2777, 2778, 2779, 2780, 2781, 2782, 2783, + 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, + 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799, + 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, + 2808, 2809, 2810, 2811, 2812, 2813, 2814, 2815, + 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, + 2824, 2825, 2826, 2827, 2828, 2829, 2830, 2831, + 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, + 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, + 2848, 2849, 2850, 2851, 2852, 2853, 2854, 2855, + 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, + 2864, 2865, 2866, 2867, 2868, 2869, 2870, 2871, + 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879, + 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887, + 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, + 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, + 2904, 2905, 2906, 2907, 2908, 2909, 2910, 2911, + 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, + 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, + 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, + 2936, 2937, 2938, 2939, 2940, 2941, 2942, 2943, + 2944, 2945, 2946, 2947, 2948, 2949, 2950, 2951, + 2952, 2953, 2954, 2955, 2956, 2957, 77, 77, + 77, 77, 77, 77, 2958, 2959, 2960, 2961, + 615, 615, 615, 2962, 2963, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 1287, 9, + 9, 2964, 2965, 2966, 2967, 2968, 2969, 2970, + 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, + 2979, 2980, 2981, 2982, 2983, 2984, 2985, 2986, + 2987, 2988, 2989, 2990, 2991, 2992, 2993, 2994, + 2995, 2996, 2997, 2998, 2999, 3000, 3001, 0, + 3002, 0, 0, 0, 0, 0, 3003, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 0, 0, 0, 0, 0, 0, 0, + 3004, 1120, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1239, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, + 615, 9, 9, 81, 93, 81, 93, 9, + 9, 9, 81, 93, 9, 81, 93, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 1162, 9, 9, 1162, 9, 81, 93, 9, + 9, 81, 93, 12, 13, 12, 13, 12, + 13, 12, 13, 9, 9, 9, 9, 9, + 595, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 1162, 1162, 9, 9, 9, + 9, 1162, 9, 2309, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 77, 77, 9, 9, 9, 12, 13, + 12, 13, 12, 13, 12, 13, 1162, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 0, 3005, 3005, 3005, 3005, + 3006, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3007, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3008, 3009, 3010, 3011, 3012, 3013, 3014, + 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, + 3023, 3024, 3025, 3026, 3027, 3028, 3029, 3030, + 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, + 3039, 3040, 3041, 3042, 3043, 3044, 3045, 3046, + 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, + 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, + 3063, 3064, 3065, 3066, 3067, 3068, 3069, 3070, + 3071, 3072, 3073, 3074, 3075, 3076, 3077, 3078, + 3079, 3080, 3081, 3082, 3083, 3084, 3085, 3086, + 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, + 3095, 3096, 3097, 3098, 3099, 3100, 3101, 3102, + 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, + 3111, 3112, 3113, 3114, 3115, 3116, 3117, 3118, + 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, + 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134, + 3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142, + 3143, 3144, 3145, 3146, 3147, 3148, 3149, 3150, + 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, + 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, + 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, + 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182, + 3183, 3184, 3185, 3186, 3187, 3188, 3189, 3190, + 3191, 3192, 3193, 3194, 3195, 3196, 3197, 3198, + 3199, 3200, 3201, 3202, 3203, 3204, 3205, 3206, + 3207, 3208, 3209, 3210, 3211, 3212, 3213, 3214, + 3215, 3216, 3217, 3218, 3219, 3220, 3221, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 0, 0, 0, + 0, 3222, 3223, 3223, 3223, 3005, 3224, 3225, + 3226, 3227, 3228, 3227, 3228, 3227, 3228, 3227, + 3228, 3227, 3228, 3005, 3005, 3227, 3228, 3227, + 3228, 3227, 3228, 3227, 3228, 3229, 3230, 3231, + 3231, 3005, 3226, 3226, 3226, 3226, 3226, 3226, + 3226, 3226, 3226, 1807, 1164, 627, 1163, 3232, + 3232, 3233, 3224, 3224, 3224, 3224, 3224, 3234, + 3005, 3235, 3236, 3237, 3224, 3225, 3238, 3005, + 77, 0, 3225, 3225, 3225, 3225, 3225, 3239, + 3225, 3225, 3225, 3225, 3240, 3241, 3242, 3243, + 3244, 3245, 3246, 3247, 3248, 3249, 3250, 3251, + 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, + 3260, 3261, 3262, 3263, 3225, 3264, 3265, 3266, + 3267, 3268, 3269, 3225, 3225, 3225, 3225, 3225, + 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277, + 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3285, 3225, 3225, + 0, 0, 3286, 3287, 3288, 3289, 3290, 3291, + 3292, 3229, 3225, 3225, 3225, 3225, 3225, 3293, + 3225, 3225, 3225, 3225, 3294, 3295, 3296, 3297, + 3298, 3299, 3300, 3301, 3302, 3303, 3304, 3305, + 3306, 3307, 3308, 3309, 3310, 3311, 3312, 3313, + 3314, 3315, 3316, 3317, 3225, 3318, 3319, 3320, + 3321, 3322, 3323, 3225, 3225, 3225, 3225, 3225, + 3324, 3325, 3326, 3327, 3328, 3329, 3330, 3331, + 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3339, 3340, 3341, 3342, 3225, 3343, 3225, 3225, + 3344, 3345, 3346, 3347, 3223, 3224, 3348, 3349, + 3350, 0, 0, 0, 0, 0, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 0, 3351, 3352, 3353, 3354, 3355, 3356, + 3357, 3358, 3359, 3360, 3361, 3362, 3363, 3364, + 3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372, + 3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, + 3381, 3382, 3383, 3384, 3385, 3386, 3387, 3388, + 3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, + 3397, 3398, 3399, 3400, 3401, 3402, 3403, 3404, + 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, + 3413, 3414, 3415, 3416, 3417, 3418, 3419, 3420, + 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, + 3429, 3430, 3431, 3432, 3433, 3434, 3435, 3436, + 3437, 3438, 3439, 3440, 3441, 3442, 3443, 3444, + 0, 3445, 3445, 3446, 3447, 3448, 3449, 3450, + 3451, 3452, 3453, 3454, 3455, 3456, 3457, 3458, + 3459, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3460, 3461, 3462, 3463, 3464, 3465, 3466, + 3467, 3468, 3469, 3470, 3471, 3472, 3473, 3474, + 3475, 3476, 3477, 3478, 3479, 3480, 3481, 3482, + 3483, 3484, 3485, 3486, 3487, 3488, 3489, 3490, + 0, 3491, 3492, 3493, 3494, 3495, 3496, 3497, + 3498, 3499, 3500, 3501, 3502, 3503, 3504, 3505, + 3506, 3507, 3508, 3509, 3510, 3511, 3512, 3513, + 3514, 3515, 3516, 3517, 3518, 3519, 3520, 3521, + 3522, 3523, 3524, 3525, 3526, 3527, 3528, 3529, + 3530, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 3531, 3532, 3533, 3534, 3535, 3536, 3537, + 3538, 3539, 3540, 3541, 3542, 3543, 3544, 3545, + 3546, 3547, 3548, 3549, 3550, 3551, 3552, 3553, + 3554, 3555, 3556, 3557, 3558, 3559, 3560, 3561, + 3562, 3563, 3564, 3565, 3566, 3567, 3568, 3569, + 3570, 3571, 3572, 3573, 3574, 3575, 3576, 3577, + 3445, 3578, 3579, 3580, 3581, 3582, 3583, 3584, + 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, + 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, + 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, + 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, + 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, + 3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, + 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, + 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648, + 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, + 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, + 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, + 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680, + 3681, 3682, 3683, 3684, 3685, 3686, 3687, 3688, + 3689, 3690, 3691, 3692, 3693, 3694, 3695, 3696, + 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, + 3705, 3706, 3707, 3708, 3709, 3710, 3711, 3712, + 3713, 3714, 3715, 3716, 3717, 3718, 3719, 3720, + 3721, 3722, 3723, 3724, 3725, 3726, 3727, 3728, + 3729, 3730, 3731, 3732, 3733, 3734, 3735, 3736, + 3737, 3738, 3739, 3740, 3741, 3742, 3743, 3744, + 3745, 3746, 3747, 3748, 3749, 3750, 3751, 3752, + 3753, 3754, 3755, 3756, 3757, 3758, 3759, 3760, + 3761, 3762, 3763, 3764, 3765, 3766, 3767, 3768, + 3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, + 3777, 3778, 3779, 3780, 3781, 3782, 3783, 3784, + 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3792, + 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800, + 3801, 3802, 3803, 3804, 3805, 3806, 3807, 3808, + 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, + 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, + 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, + 3833, 3834, 3835, 3836, 3837, 3838, 3839, 3840, + 3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, + 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, + 3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, + 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3872, + 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, + 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, + 3889, 3890, 3891, 3892, 3893, 3894, 3895, 3896, + 3897, 3898, 3899, 3900, 3901, 3902, 3903, 3904, + 3905, 3906, 3907, 3908, 3909, 3910, 3911, 3912, + 3913, 3914, 3915, 3916, 3917, 3918, 3919, 3920, + 3921, 3922, 3923, 3924, 3925, 3926, 3927, 3928, + 3929, 3930, 3931, 3932, 3933, 3934, 3935, 3936, + 3937, 3938, 3939, 3940, 3941, 3942, 3943, 3944, + 3945, 3946, 3947, 3948, 3949, 3950, 3951, 3952, + 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960, + 3961, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3224, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 0, 0, + 0, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 3005, 3005, 3005, 3005, 3005, 3005, 3005, 3005, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 596, 596, 596, 596, 596, 596, 1120, + 1120, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 596, 9, 9, + 9, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 346, 346, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3962, 3963, 3964, 3965, 3966, 3967, 3968, + 3969, 3970, 3971, 3972, 3973, 3974, 3975, 3976, + 3977, 3978, 3979, 3980, 3981, 3982, 3983, 3984, + 3985, 3986, 3987, 3988, 3989, 3990, 3991, 3992, + 3993, 3994, 3995, 3996, 3997, 3998, 3999, 4000, + 4001, 4002, 4003, 4004, 4005, 4006, 4007, 346, + 615, 915, 915, 915, 9, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 9, + 595, 4008, 4009, 4010, 4011, 4012, 4013, 4014, + 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, + 4023, 4024, 4025, 4026, 4027, 4028, 4029, 4030, + 4031, 4032, 4033, 4034, 4035, 4036, 4037, 615, + 615, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 615, 615, 1120, 1120, 1120, 1120, 1120, + 1120, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 595, 595, 595, 595, 595, 595, 595, 595, + 595, 47, 47, 4038, 4039, 4040, 4041, 4042, + 4043, 4044, 4045, 4046, 4047, 4048, 4049, 4050, + 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, + 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, + 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, + 4075, 4076, 4077, 4078, 4079, 4080, 4081, 4082, + 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, + 4091, 4092, 4093, 4094, 4095, 4096, 4097, 4098, + 4099, 4100, 4101, 4102, 4103, 4104, 4105, 4106, + 4107, 4108, 4109, 4110, 4111, 4112, 4113, 4114, + 4115, 4116, 4117, 4118, 4119, 4120, 4121, 4122, + 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, + 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, + 4139, 595, 4140, 4140, 4141, 4142, 4143, 4144, + 346, 4145, 4146, 4147, 4148, 4149, 4150, 4151, + 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, + 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, + 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4175, + 4176, 4177, 4178, 4179, 4180, 4181, 4182, 4183, + 4184, 4185, 4186, 4187, 4188, 4189, 4190, 4191, + 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, + 4200, 4201, 4202, 4203, 0, 0, 0, 0, + 0, 4204, 4205, 0, 4206, 0, 4207, 4208, + 4209, 4210, 4211, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4212, 4213, 4214, 4215, 4216, + 346, 4217, 4218, 4219, 346, 346, 346, 346, + 346, 346, 346, 1226, 346, 346, 346, 1239, + 346, 346, 346, 346, 1226, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1231, 1231, 1226, 1226, + 1231, 77, 77, 77, 77, 1239, 0, 0, + 0, 1258, 1258, 1258, 1258, 1258, 1258, 914, + 914, 11, 84, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 1231, 1231, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 1231, 1231, 1231, + 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, + 1231, 1231, 1231, 1231, 1231, 1239, 1226, 0, + 0, 0, 0, 0, 0, 0, 0, 1120, + 1120, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 346, 346, 346, 346, 346, + 346, 1120, 1120, 1120, 346, 1120, 346, 346, + 1226, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 1226, + 1226, 1226, 1226, 1226, 628, 628, 628, 1120, + 1120, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1231, 1535, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1120, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, + 1437, 1437, 1437, 1437, 1437, 1437, 0, 0, + 0, 1226, 1226, 1226, 1231, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1249, 1231, 1231, 1226, + 1226, 1226, 1226, 1231, 1231, 1226, 1226, 1231, + 1231, 1535, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 0, + 596, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 1120, + 1120, 346, 346, 346, 346, 346, 1226, 596, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1226, 1226, 1226, 1226, 1226, 1226, + 1231, 1231, 1226, 1226, 1231, 1231, 1226, 1226, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 1226, 346, 346, 346, + 346, 346, 346, 346, 346, 1226, 1231, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 1120, 1120, 1120, + 1120, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 596, 346, 346, 346, 346, 346, 346, + 914, 914, 914, 346, 1348, 1226, 1348, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 615, 346, 615, 615, 628, 346, 346, + 615, 615, 346, 346, 346, 346, 346, 615, + 615, 346, 615, 346, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 346, 346, 596, 1120, + 1120, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1231, 1226, 1226, 1231, + 1231, 1120, 1120, 346, 596, 596, 1231, 1239, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 346, 346, 346, 346, 346, 346, + 0, 0, 346, 346, 346, 346, 346, 346, + 0, 0, 346, 346, 346, 346, 346, 346, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 4220, 4221, 4222, 4223, 4224, 4225, 4226, + 4227, 4228, 4229, 4230, 4231, 4232, 4233, 4234, + 4235, 4236, 4237, 4238, 4239, 4240, 4241, 4242, + 4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250, + 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, + 4259, 4260, 4261, 4262, 4140, 4263, 4264, 4265, + 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, + 4274, 4275, 4276, 47, 47, 0, 0, 0, + 0, 4277, 4278, 4279, 4280, 4281, 4282, 4283, + 4284, 4285, 4286, 4287, 4288, 4289, 4290, 4291, + 4292, 4293, 4294, 4295, 4296, 4297, 4298, 4299, + 4300, 4301, 4302, 4303, 4304, 4305, 4306, 4307, + 4308, 4309, 4310, 4311, 4312, 4313, 4314, 4315, + 4316, 4317, 4318, 4319, 4320, 4321, 4322, 4323, + 4324, 4325, 4326, 4327, 4328, 4329, 4330, 4331, + 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, + 4340, 4341, 4342, 4343, 4344, 4345, 4346, 4347, + 4348, 4349, 4350, 4351, 4352, 4353, 4354, 4355, + 4356, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1231, 1231, 1226, 1231, + 1231, 1226, 1231, 1231, 1120, 1231, 1239, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4357, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4357, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4358, 4358, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 0, 0, 0, 0, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + 1441, 1441, 1441, 1441, 1441, 0, 0, 0, + 0, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4359, 4359, 4359, 4359, 4359, 4359, + 4359, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4361, 4362, 4363, 4364, 4365, 4366, 4367, + 4368, 4368, 4369, 4370, 4371, 4372, 4373, 4374, + 4375, 4376, 4377, 4378, 4379, 4380, 4381, 4382, + 4383, 4384, 4385, 4386, 4387, 4388, 4389, 4390, + 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, + 4399, 4400, 4401, 4402, 4403, 4404, 4405, 4406, + 4407, 4408, 4409, 4410, 4411, 4412, 4413, 4414, + 4415, 4416, 4417, 4418, 4419, 4420, 4421, 4422, + 4423, 4424, 4425, 4426, 4427, 4428, 4429, 4430, + 4431, 4432, 4433, 4434, 4435, 4436, 4437, 4438, + 4439, 4440, 4441, 4442, 4443, 4444, 4445, 4446, + 4447, 4448, 4449, 4450, 4451, 4380, 4452, 4453, + 4454, 4455, 4456, 4457, 4458, 4459, 4460, 4461, + 4462, 4463, 4464, 4465, 4466, 4467, 4468, 4469, + 4470, 4471, 4472, 4473, 4474, 4475, 4476, 4477, + 4478, 4479, 4480, 4481, 4482, 4483, 4484, 4485, + 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4493, + 4494, 4495, 4496, 4497, 4498, 4499, 4500, 4501, + 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, + 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, + 4518, 4519, 4470, 4520, 4521, 4522, 4523, 4524, + 4525, 4526, 4527, 4454, 4528, 4529, 4530, 4531, + 4532, 4533, 4534, 4535, 4536, 4537, 4538, 4539, + 4540, 4541, 4542, 4543, 4544, 4545, 4546, 4547, + 4380, 4548, 4549, 4550, 4551, 4552, 4553, 4554, + 4555, 4556, 4557, 4558, 4559, 4560, 4561, 4562, + 4563, 4564, 4565, 4566, 4567, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 4456, 4575, 4576, 4577, + 4578, 4579, 4580, 4581, 4582, 4583, 4584, 4585, + 4586, 4587, 4588, 4589, 4590, 4591, 4592, 4593, + 4594, 4595, 4596, 4597, 4598, 4599, 4600, 4601, + 4602, 4603, 4604, 4605, 4606, 4607, 4608, 4609, + 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, + 4618, 4619, 4620, 4621, 4622, 4623, 4624, 3225, + 3225, 4625, 3225, 4626, 3225, 3225, 4627, 4628, + 4629, 4630, 4631, 4632, 4633, 4634, 4635, 4636, + 3225, 4637, 3225, 4638, 3225, 3225, 4639, 4640, + 3225, 3225, 3225, 4641, 4642, 4643, 4644, 4645, + 4646, 4647, 4648, 4649, 4650, 4651, 4652, 4653, + 4654, 4655, 4656, 4657, 4658, 4659, 4660, 4661, + 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, + 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, + 4678, 4679, 4680, 4681, 4682, 4683, 4684, 4685, + 4509, 4686, 4687, 4688, 4689, 4690, 4691, 4691, + 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, + 4639, 4700, 4701, 4702, 4703, 4704, 4705, 0, + 0, 4706, 4707, 4708, 4709, 4710, 4711, 4712, + 4713, 4653, 4714, 4715, 4716, 4625, 4717, 4718, + 4719, 4720, 4721, 4722, 4723, 4724, 4725, 4726, + 4727, 4728, 4662, 4729, 4663, 4730, 4731, 4732, + 4733, 4734, 4626, 4401, 4735, 4736, 4737, 4471, + 4558, 4738, 4739, 4670, 4740, 4671, 4741, 4742, + 4743, 4628, 4744, 4745, 4746, 4747, 4748, 4629, + 4749, 4750, 4751, 4752, 4753, 4754, 4685, 4755, + 4756, 4509, 4757, 4689, 4758, 4759, 4760, 4761, + 4762, 4694, 4763, 4638, 4764, 4695, 4452, 4765, + 4696, 4766, 4698, 4767, 4768, 4769, 4770, 4771, + 4700, 4634, 4772, 4701, 4773, 4702, 4774, 4368, + 4775, 4776, 4777, 4778, 4779, 4780, 4781, 4782, + 4783, 4784, 4785, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4786, 4787, 4788, 4789, 4790, 4791, 4792, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4793, 4794, 4795, 4796, + 4797, 0, 0, 0, 0, 0, 4798, 4799, + 4800, 4801, 4802, 4803, 4804, 4805, 4806, 4807, + 4808, 4809, 4810, 4811, 4812, 4813, 4814, 4815, + 4816, 4817, 4818, 4819, 4820, 4821, 4822, 4823, + 0, 4824, 4825, 4826, 4827, 4828, 0, 4829, + 0, 4830, 4831, 0, 4832, 4833, 0, 4834, + 4835, 4836, 4837, 4838, 4839, 4840, 4841, 4842, + 4843, 4844, 4845, 4846, 4847, 4848, 4849, 4850, + 4851, 4852, 4853, 4854, 4855, 4856, 4857, 4858, + 4859, 4860, 4861, 4862, 4863, 4864, 4865, 4866, + 4867, 4868, 4869, 4870, 4871, 4872, 4873, 4874, + 4875, 4876, 4877, 4878, 4879, 4880, 4881, 4882, + 4883, 4884, 4885, 4886, 4887, 4888, 4889, 4890, + 4891, 4892, 4893, 4894, 4895, 4896, 4897, 4898, + 4899, 4900, 4901, 4902, 4903, 4904, 4905, 4906, + 4907, 4908, 4909, 4910, 4911, 4912, 4913, 4914, + 4915, 4916, 4917, 4918, 4919, 4920, 4921, 4922, + 4923, 4924, 4925, 4926, 4927, 4928, 4929, 4930, + 4931, 4932, 4933, 4934, 4935, 4936, 4937, 4938, + 4939, 4940, 4941, 1230, 1230, 1230, 1230, 1230, + 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, + 1230, 1230, 1230, 1230, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4942, 4943, 4944, 4945, + 4946, 4947, 4948, 4949, 4950, 4951, 4952, 4953, + 4954, 4955, 4956, 4957, 4958, 4959, 4960, 4961, + 4962, 4963, 4964, 4965, 4966, 4967, 4968, 4969, + 4970, 4971, 4972, 4973, 4974, 4975, 4976, 4977, + 4978, 4979, 4980, 4981, 4982, 4983, 4984, 4985, + 4986, 4987, 4988, 4989, 4980, 4990, 4991, 4992, + 4993, 4994, 4995, 4996, 4997, 4998, 4999, 5000, + 5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008, + 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, + 5017, 5018, 5019, 5020, 5021, 5022, 5023, 5024, + 5025, 5026, 5027, 5028, 5029, 5030, 5031, 5032, + 5033, 5034, 5035, 5036, 5037, 5038, 5039, 5040, + 5041, 5042, 5043, 5044, 5045, 5046, 5047, 5048, + 5049, 5050, 5051, 5052, 5053, 5054, 5055, 5056, + 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, + 5073, 5074, 5075, 5076, 5077, 5078, 5079, 5080, + 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088, + 5089, 4981, 5090, 5091, 5092, 5093, 5094, 5095, + 5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103, + 5104, 5105, 5106, 5107, 5108, 5109, 5110, 5111, + 5112, 5113, 5114, 5115, 5116, 5117, 5118, 5119, + 5120, 5121, 5122, 5123, 5124, 5125, 5126, 5127, + 5128, 5129, 5130, 5131, 5132, 5133, 5134, 5135, + 5136, 5137, 5138, 5139, 5140, 5141, 5142, 5143, + 5144, 5145, 5146, 5147, 5148, 5149, 5150, 5151, + 5152, 5153, 5154, 5155, 5156, 5157, 5158, 5159, + 5160, 5161, 5162, 5163, 5164, 5165, 5166, 5167, + 5168, 5169, 5170, 5171, 5172, 5173, 5174, 5175, + 5176, 5177, 5178, 5179, 5180, 5181, 5182, 5183, + 5184, 5185, 5186, 5187, 5188, 5189, 5190, 5191, + 5192, 5193, 5194, 5195, 5196, 5197, 5198, 5199, + 5200, 5201, 5202, 5203, 5204, 5205, 5206, 5207, + 5208, 5209, 5210, 5211, 5212, 5213, 5214, 5215, + 5216, 5217, 5218, 5219, 5220, 5221, 5222, 5223, + 5224, 5225, 5226, 5227, 5228, 5229, 5230, 5231, + 5232, 5233, 5234, 5235, 5236, 5237, 5238, 5239, + 5240, 5241, 5242, 5243, 5244, 5245, 5246, 5247, + 5248, 5249, 5250, 5251, 5252, 5253, 5254, 5255, + 5256, 5257, 5258, 5259, 5260, 5261, 5262, 5263, + 5264, 5265, 5266, 5267, 5268, 5269, 5270, 5271, + 5272, 5273, 5274, 5275, 5276, 5277, 5278, 5279, + 5280, 5281, 5282, 5283, 5284, 5285, 5286, 5287, + 5288, 5289, 5290, 5291, 5292, 5293, 5294, 5295, + 5296, 5297, 5298, 5299, 5300, 5301, 5302, 5303, + 2309, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 5304, 5305, 5306, 5307, 5308, 5309, 5310, + 5311, 5312, 5313, 5314, 5315, 5316, 5317, 5318, + 5319, 5320, 5321, 5322, 5323, 5324, 5325, 5326, + 5327, 5328, 5329, 5330, 5331, 5332, 5333, 5334, + 5335, 5336, 5337, 5338, 5339, 5340, 5341, 5342, + 5343, 5344, 5345, 5346, 5347, 5348, 5349, 5350, + 5351, 5352, 5353, 5354, 5355, 5356, 5357, 5358, + 5359, 5360, 5361, 5362, 5363, 5364, 5365, 5366, + 5367, 0, 0, 5368, 5369, 5370, 5371, 5372, + 5373, 5374, 5375, 5376, 5377, 5378, 5379, 5380, + 5381, 5382, 5383, 5384, 5385, 5386, 5387, 5388, + 5389, 5390, 5391, 5392, 5393, 5394, 5395, 5396, + 5397, 5398, 5399, 5400, 5401, 5402, 5403, 5404, + 5405, 5406, 5407, 5408, 5409, 5410, 5411, 5412, + 5413, 5414, 5415, 5416, 5417, 5418, 5419, 5420, + 5421, 0, 0, 0, 0, 0, 0, 0, + 77, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5422, 5423, 5424, 5425, 5426, 5427, 5428, + 5429, 5430, 5431, 5432, 5433, 5434, 77, 77, + 77, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 5435, 5436, 5437, 5438, 5439, 5440, 5441, + 5442, 5443, 5444, 0, 0, 0, 0, 0, + 0, 615, 615, 615, 615, 615, 615, 615, + 628, 628, 628, 628, 628, 628, 628, 615, + 615, 5445, 5446, 5447, 5448, 5448, 5449, 5450, + 5451, 5452, 5453, 5454, 5455, 5456, 5457, 5458, + 5459, 5460, 5461, 5462, 5463, 5464, 3223, 3223, + 5465, 5466, 5467, 5467, 5467, 5467, 5468, 5468, + 5468, 5469, 5470, 5471, 0, 5472, 5473, 5474, + 5475, 5476, 5477, 5478, 5479, 5480, 5481, 5482, + 5483, 5484, 5485, 5486, 5487, 5488, 5489, 5490, + 0, 5491, 5492, 5493, 5494, 0, 0, 0, + 0, 5495, 5496, 5497, 1192, 5498, 0, 5499, + 5500, 5501, 5502, 5503, 5504, 5505, 5506, 5507, + 5508, 5509, 5510, 5511, 5512, 5513, 5514, 5515, + 5516, 5517, 5518, 5519, 5520, 5521, 5522, 5523, + 5524, 5525, 5526, 5527, 5528, 5529, 5530, 5531, + 5532, 5533, 5534, 5535, 5536, 5537, 5538, 5539, + 5540, 5541, 5542, 5543, 5544, 5545, 5546, 5547, + 5548, 5549, 5550, 5551, 5552, 5553, 5554, 5555, + 5556, 5557, 5558, 5559, 5560, 5561, 5562, 5563, + 5564, 5565, 5566, 5567, 5568, 5569, 5570, 5571, + 5572, 5573, 5574, 5575, 5576, 5577, 5578, 5579, + 5580, 5581, 5582, 5583, 5584, 5585, 5586, 5587, + 5588, 5589, 5590, 5591, 5592, 5593, 5594, 5595, + 5596, 5597, 5598, 5599, 5600, 5601, 5602, 5603, + 5604, 5605, 5606, 5607, 5608, 5609, 5610, 5611, + 5612, 5613, 5614, 5615, 5616, 5617, 5618, 5619, + 5620, 5621, 5622, 5623, 5624, 5625, 5626, 5627, + 5628, 5629, 5630, 5631, 5632, 5633, 0, 0, + 1536, 0, 5634, 5635, 5636, 5637, 5638, 5639, + 5640, 5641, 5642, 5643, 5644, 5645, 5646, 5647, + 5648, 5649, 5650, 5651, 5652, 5653, 5654, 5655, + 5656, 5657, 5658, 5659, 5660, 5661, 5662, 5663, + 5664, 5665, 5666, 5667, 5668, 5669, 5670, 5671, + 5672, 5673, 5674, 5675, 5676, 5677, 5678, 5679, + 5680, 5681, 5682, 5683, 5684, 5685, 5686, 5687, + 5688, 5689, 5690, 5691, 5692, 5693, 5694, 5695, + 5696, 5697, 5698, 5699, 5700, 5701, 5702, 5703, + 5704, 5705, 5706, 5707, 5708, 5709, 5710, 5711, + 5712, 5713, 5714, 5715, 5716, 5717, 5718, 5719, + 5720, 5721, 5722, 5723, 5724, 5725, 5726, 5727, + 5728, 5729, 5730, 5731, 5732, 5733, 5734, 5735, + 5736, 5737, 5738, 5739, 5740, 5741, 5742, 5743, + 5744, 5745, 5746, 5747, 5748, 5749, 5750, 5751, + 5752, 5753, 5754, 5755, 5756, 5757, 5758, 5759, + 5760, 5761, 5762, 5763, 5764, 5765, 5766, 5767, + 5768, 5769, 5770, 5771, 5772, 5773, 5774, 5775, + 5776, 5777, 5778, 5779, 5780, 5781, 5782, 5783, + 5784, 5785, 5786, 5787, 5788, 5789, 5790, 5791, + 5792, 5793, 5794, 5795, 5796, 5797, 5798, 5799, + 5800, 5801, 5802, 5803, 5804, 5805, 5806, 5807, + 5808, 5809, 5810, 5811, 5812, 5813, 5814, 5815, + 5816, 5817, 5818, 5819, 5820, 5821, 5822, 5823, + 0, 0, 0, 5824, 5825, 5826, 5827, 5828, + 5829, 0, 0, 5830, 5831, 5832, 5833, 5834, + 5835, 0, 0, 5836, 5837, 5838, 5839, 5840, + 5841, 0, 0, 5842, 5843, 5844, 0, 0, + 0, 5845, 5846, 5847, 5848, 5849, 5850, 5851, + 0, 5852, 5853, 5854, 5855, 5856, 5857, 5858, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5859, 5859, 5859, 77, 77, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 0, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 0, 346, 346, 0, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 0, 0, 0, 0, + 0, 1120, 9, 1120, 0, 0, 0, 0, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 0, 0, 0, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 5860, 5860, 5860, 5860, 5860, 5860, 5860, + 5860, 5860, 5860, 5860, 5860, 5860, 5860, 5860, + 5860, 5860, 5860, 5860, 5860, 5860, 5860, 5860, + 5860, 5860, 5860, 5860, 5860, 5860, 5860, 5860, + 5860, 5860, 5860, 5860, 5860, 5860, 5860, 5860, + 5860, 5860, 5860, 5860, 5860, 5860, 5860, 5860, + 5860, 5860, 5860, 5860, 5860, 5860, 1287, 1287, + 1287, 1287, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 1287, 1287, 77, 914, 914, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 0, 0, + 0, 77, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 628, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 628, 5861, 5861, 5861, 5861, 5861, 5861, + 5861, 5861, 5861, 5861, 5861, 5861, 5861, 5861, + 5861, 5861, 5861, 5861, 5861, 5861, 5861, 5861, + 5861, 5861, 5861, 5861, 5861, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 1258, 1258, 1258, 1258, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1534, 346, 346, 346, 346, 346, + 346, 346, 346, 1534, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 615, + 615, 615, 615, 615, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 0, + 1120, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 1120, 1534, 1534, 1534, 1534, 1534, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5862, 5863, 5864, 5865, 5866, 5867, 5868, + 5869, 5870, 5871, 5872, 5873, 5874, 5875, 5876, + 5877, 5878, 5879, 5880, 5881, 5882, 5883, 5884, + 5885, 5886, 5887, 5888, 5889, 5890, 5891, 5892, + 5893, 5894, 5895, 5896, 5897, 5898, 5899, 5900, + 5901, 5902, 5903, 5904, 5905, 5906, 5907, 5908, + 5909, 5910, 5911, 5912, 5913, 5914, 5915, 5916, + 5917, 5918, 5919, 5920, 5921, 5922, 5923, 5924, + 5925, 5926, 5927, 5928, 5929, 5930, 5931, 5932, + 5933, 5934, 5935, 5936, 5937, 5938, 5939, 5940, + 5941, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 5942, 5943, 5944, 5945, 5946, 5947, 5948, + 5949, 5950, 5951, 5952, 5953, 5954, 5955, 5956, + 5957, 5958, 5959, 5960, 5961, 5962, 5963, 5964, + 5965, 5966, 5967, 5968, 5969, 5970, 5971, 5972, + 5973, 5974, 5975, 5976, 5977, 0, 0, 0, + 0, 5978, 5979, 5980, 5981, 5982, 5983, 5984, + 5985, 5986, 5987, 5988, 5989, 5990, 5991, 5992, + 5993, 5994, 5995, 5996, 5997, 5998, 5999, 6000, + 6001, 6002, 6003, 6004, 6005, 6006, 6007, 6008, + 6009, 6010, 6011, 6012, 6013, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1120, 6014, 6015, 6016, 6017, 6018, 6019, 6020, + 6021, 6022, 6023, 6024, 0, 6025, 6026, 6027, + 6028, 6029, 6030, 6031, 6032, 6033, 6034, 6035, + 6036, 6037, 6038, 6039, 0, 6040, 6041, 6042, + 6043, 6044, 6045, 6046, 0, 6047, 6048, 0, + 6049, 6050, 6051, 6052, 6053, 6054, 6055, 6056, + 6057, 6058, 6059, 0, 6060, 6061, 6062, 6063, + 6064, 6065, 6066, 6067, 6068, 6069, 6070, 6071, + 6072, 6073, 6074, 0, 6075, 6076, 6077, 6078, + 6079, 6080, 6081, 0, 6082, 6083, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6084, 6085, 6086, 6087, 6088, 6089, 0, + 6090, 6091, 6092, 6093, 6094, 6095, 6096, 6097, + 6098, 6099, 6100, 6101, 6102, 6103, 6104, 6105, + 6106, 6107, 6108, 6109, 6110, 6111, 6112, 6113, + 6114, 6115, 6116, 6117, 6118, 6119, 6120, 6121, + 6122, 6123, 6124, 6125, 6126, 6127, 6128, 6129, + 6130, 6131, 0, 6132, 6133, 6134, 6135, 6136, + 6137, 6138, 6139, 6140, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 0, + 0, 1183, 0, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 0, + 1183, 1183, 0, 0, 0, 1183, 0, 0, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 0, + 1180, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 6142, 6142, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 0, 0, 0, 0, 0, 0, 0, 0, + 6141, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 0, 1183, 1183, 0, + 0, 0, 0, 0, 6141, 6141, 6141, 6141, + 6141, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 6141, + 6141, 6141, 6141, 6141, 6141, 0, 0, 0, + 9, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 0, 0, 0, 0, 0, + 1180, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 0, 0, 0, 0, 6141, 6141, 1183, + 1183, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 0, 0, 6141, 6141, 6141, 6141, 6141, + 6141, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 1183, 1226, 1226, 1226, 0, 1226, 1226, + 0, 0, 0, 0, 0, 1226, 628, 1226, + 615, 1183, 1183, 1183, 1183, 0, 1183, 1183, + 1183, 0, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 0, + 0, 615, 641, 628, 0, 0, 0, 0, + 1239, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 6141, 0, 0, 0, 0, 0, 0, + 0, 1180, 1180, 1180, 1180, 1180, 1180, 1180, + 1180, 1180, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 6141, 6141, + 1180, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 6141, 6141, + 6141, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 6142, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 615, 628, + 0, 0, 0, 0, 6141, 6141, 6141, 6141, + 6141, 1180, 1180, 1180, 1180, 1180, 1180, 1180, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 0, + 0, 0, 9, 9, 9, 9, 9, 9, + 9, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 0, + 0, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 0, 0, 0, 0, + 0, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 0, 0, 0, 0, 0, + 0, 0, 1180, 1180, 1180, 1180, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6143, 6144, 6145, 6146, 6147, 6148, 6149, + 6150, 6151, 6152, 6153, 6154, 6155, 6156, 6157, + 6158, 6159, 6160, 6161, 6162, 6163, 6164, 6165, + 6166, 6167, 6168, 6169, 6170, 6171, 6172, 6173, + 6174, 6175, 6176, 6177, 6178, 6179, 6180, 6181, + 6182, 6183, 6184, 6185, 6186, 6187, 6188, 6189, + 6190, 6191, 6192, 6193, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6194, 6195, 6196, 6197, 6198, 6199, 6200, + 6201, 6202, 6203, 6204, 6205, 6206, 6207, 6208, + 6209, 6210, 6211, 6212, 6213, 6214, 6215, 6216, + 6217, 6218, 6219, 6220, 6221, 6222, 6223, 6224, + 6225, 6226, 6227, 6228, 6229, 6230, 6231, 6232, + 6233, 6234, 6235, 6236, 6237, 6238, 6239, 6240, + 6241, 6242, 6243, 6244, 0, 0, 0, 0, + 0, 0, 0, 6141, 6141, 6141, 6141, 6141, + 6141, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 615, 615, 615, + 615, 0, 0, 0, 0, 0, 0, 0, + 0, 1210, 1210, 1210, 1210, 1210, 1210, 1210, + 1210, 1210, 1210, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6245, 6245, 6245, 6245, 6245, 6245, 6245, + 6245, 6245, 6245, 6245, 6245, 6245, 6245, 6245, + 6245, 6245, 6245, 6245, 6245, 6245, 6245, 6245, + 6245, 6245, 6245, 6245, 6245, 6245, 6245, 6245, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 0, 615, 615, 1178, 0, + 0, 1183, 1183, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 628, 628, + 628, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 6141, 6141, + 6141, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 1183, 0, 0, 0, 0, 0, 0, 0, + 0, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 628, + 628, 615, 615, 615, 628, 615, 628, 628, + 628, 628, 6246, 6246, 6246, 6246, 1187, 1187, + 1187, 1187, 1187, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 615, 628, 615, 628, 1180, + 1180, 1180, 1180, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 6141, 6141, + 6141, 6141, 6141, 6141, 6141, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1231, 1226, 1231, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1239, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 0, + 0, 0, 0, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1239, 346, 346, 1226, 1226, 346, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1239, 1226, 1226, 1231, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 6247, 6248, 6249, 6250, 346, 346, + 346, 346, 346, 346, 346, 346, 6251, 346, + 346, 346, 346, 346, 6252, 346, 346, 346, + 346, 1231, 1231, 1231, 1226, 1226, 1226, 1226, + 1231, 1231, 1239, 6253, 1120, 1120, 6254, 1120, + 1120, 1120, 1120, 1226, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6254, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 615, 615, 615, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 6255, 1226, 1226, 1226, 1226, 1231, 1226, 6256, + 6257, 1226, 6258, 6259, 1239, 1239, 0, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1120, 1120, 1120, 1120, 346, 1231, 1231, + 346, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1249, 1120, 1120, 346, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1226, 1226, 1231, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1231, 1231, 1231, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1231, 1535, 346, 1304, 1304, 346, 1120, 1120, + 1120, 1120, 1226, 1249, 1226, 1226, 1120, 1231, + 1226, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 346, 1120, 346, 1120, 1120, + 1120, 0, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 0, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 1231, 1231, 1231, + 1226, 1226, 1226, 1231, 1231, 1226, 1535, 1249, + 1226, 1120, 1120, 1120, 1120, 1120, 1120, 1226, + 346, 346, 1226, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 0, 346, 346, 346, 346, 0, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 0, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1120, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 1226, 1231, 1231, 1231, 1226, 1226, 1226, 1226, + 1226, 1226, 1249, 1239, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 1226, 1226, 1231, 1231, 0, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 0, + 346, 346, 0, 0, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 0, 346, 346, + 346, 346, 346, 0, 1249, 1249, 346, 6260, + 1231, 1226, 1231, 1231, 1231, 1231, 0, 0, + 6261, 1231, 0, 0, 6262, 6263, 1535, 0, + 0, 346, 0, 0, 0, 0, 0, 0, + 6264, 0, 0, 0, 0, 0, 346, 346, + 346, 346, 346, 1231, 1231, 0, 0, 615, + 615, 615, 615, 615, 615, 615, 0, 0, + 0, 615, 615, 615, 615, 615, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 1231, 1231, + 1231, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1231, 1231, 1239, 1226, 1226, 1231, 1249, + 346, 346, 346, 346, 1120, 1120, 1120, 1120, + 1120, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1120, 1120, 0, 1120, 615, + 346, 346, 346, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 6265, 1231, 1231, 1226, 1226, 1226, 1226, + 1226, 1226, 6266, 6267, 6268, 6269, 6270, 6271, + 1226, 1226, 1231, 1239, 1249, 346, 346, 1120, + 346, 0, 0, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 6272, 1231, 1231, 1226, 1226, 1226, 1226, 0, + 0, 6273, 6274, 6275, 6276, 1226, 1226, 1231, + 1239, 1249, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 346, 346, 346, 346, 1226, 1226, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 1231, 1231, 1231, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1231, 1231, 1226, 1231, + 1239, 1226, 1120, 1120, 1120, 346, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1226, 1231, 1226, 1231, + 1231, 1226, 1226, 1226, 1226, 1226, 1226, 1535, + 1249, 346, 1120, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 0, 0, 1226, 1226, + 1226, 1348, 1348, 1226, 1226, 1226, 1226, 1231, + 1226, 1226, 1226, 1226, 1239, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1258, 1258, 1120, 1120, 1120, + 914, 346, 346, 346, 346, 346, 346, 346, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 1231, 1231, 1231, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1231, 1239, 1249, 1120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6277, 6278, 6279, 6280, 6281, 6282, 6283, + 6284, 6285, 6286, 6287, 6288, 6289, 6290, 6291, + 6292, 6293, 6294, 6295, 6296, 6297, 6298, 6299, + 6300, 6301, 6302, 6303, 6304, 6305, 6306, 6307, + 6308, 6309, 6310, 6311, 6312, 6313, 6314, 6315, + 6316, 6317, 6318, 6319, 6320, 6321, 6322, 6323, + 6324, 6325, 6326, 6327, 6328, 6329, 6330, 6331, + 6332, 6333, 6334, 6335, 6336, 6337, 6338, 6339, + 6340, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 0, 346, 0, 0, 346, 346, 346, + 346, 346, 346, 346, 346, 0, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 6341, 1231, 1231, 1231, 1231, 6342, 0, + 1231, 6343, 0, 0, 1226, 1226, 1535, 1239, + 1304, 1231, 1304, 1231, 1249, 1120, 1120, 1120, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 0, 0, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1231, 1231, 1231, 1226, 1226, 1226, + 1226, 0, 0, 1226, 1226, 1231, 1231, 1231, + 1231, 1239, 346, 1120, 346, 1231, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 1226, 1226, 1226, 1226, 1226, 1226, + 6344, 6344, 1226, 1226, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1226, 1239, 1226, 1226, + 1226, 1226, 1231, 1304, 1226, 1226, 1226, 1226, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1239, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 1226, 1226, 1226, 1226, 1226, 1226, + 1231, 1231, 1226, 1226, 1226, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 1304, 1304, 1304, + 1304, 1304, 1304, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1231, 1226, 1239, 1120, 1120, 1120, 346, 1120, + 1120, 1120, 1120, 1120, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 0, 0, 0, 0, 0, + 0, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 1231, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 0, 1226, 1226, 1226, 1226, 1226, 1226, 1231, + 6345, 346, 1120, 1120, 1120, 1120, 1120, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 0, 0, + 0, 1120, 1120, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 0, 0, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 0, 1231, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1231, 1226, 1226, 1231, 1226, 1226, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 0, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1226, 1226, 1226, 1226, 1226, 1226, + 0, 0, 0, 1226, 0, 1226, 1226, 0, + 1226, 1226, 1226, 1249, 1226, 1239, 1239, 1304, + 1226, 0, 0, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 0, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 1231, 1231, 1231, 1231, 1231, + 0, 1226, 1226, 0, 1231, 1231, 1226, 1231, + 1239, 346, 0, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 1226, 1226, 1231, 1231, + 1120, 1120, 0, 0, 0, 0, 0, 0, + 0, 1226, 1226, 1304, 1231, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 1231, 1231, 1226, + 1226, 1226, 1226, 1226, 0, 0, 0, 1231, + 1231, 1226, 1535, 1239, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 77, 77, + 77, 77, 77, 77, 77, 77, 11, 11, + 11, 11, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1120, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, + 0, 1120, 1120, 1120, 1120, 1120, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 1120, 1120, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 6346, 6346, 6346, 6346, 6346, 6346, 6346, + 6346, 6346, 6346, 6346, 6346, 6346, 6346, 6346, + 6346, 1226, 346, 346, 346, 346, 346, 346, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 1120, + 1120, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 0, + 0, 641, 641, 641, 641, 641, 1120, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 615, 615, 615, 615, 615, 615, 615, + 1120, 1120, 1120, 1120, 1120, 914, 914, 914, + 914, 596, 596, 596, 596, 1120, 914, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 0, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 0, 0, 0, 0, 0, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6347, 6348, 6349, 6350, 6351, 6352, 6353, + 6354, 6355, 6356, 6357, 6358, 6359, 6360, 6361, + 6362, 6363, 6364, 6365, 6366, 6367, 6368, 6369, + 6370, 6371, 6372, 6373, 6374, 6375, 6376, 6377, + 6378, 6379, 6380, 6381, 6382, 6383, 6384, 6385, + 6386, 6387, 6388, 6389, 6390, 6391, 6392, 6393, + 6394, 6395, 6396, 6397, 6398, 6399, 6400, 6401, + 6402, 6403, 6404, 6405, 6406, 6407, 6408, 6409, + 6410, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1120, 1120, 1120, 1120, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 0, 0, 0, 0, + 1226, 346, 1231, 1231, 1231, 1231, 1231, 1231, + 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, + 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, + 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, + 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, + 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, + 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, + 1231, 0, 0, 0, 0, 0, 0, 0, + 1226, 1226, 1226, 1226, 596, 596, 596, 596, + 596, 596, 596, 596, 596, 596, 596, 596, + 596, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3224, 3224, 3223, 3224, 1226, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6411, 6411, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 0, 0, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3224, 3224, 3224, 3224, 0, 3224, 3224, + 3224, 3224, 3224, 3224, 3224, 0, 3224, 3224, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3225, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 0, 0, 3225, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3225, 3225, 3225, + 3225, 0, 0, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 0, 0, 914, 1226, 641, + 1120, 1536, 1536, 1536, 1536, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 0, + 0, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 0, 0, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 6412, 6413, 914, 914, 914, 914, 914, 6414, + 6415, 6416, 6417, 6418, 6419, 6420, 6421, 6422, + 641, 641, 641, 914, 914, 914, 6423, 6424, + 6425, 6426, 6427, 6428, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 628, 628, 628, 628, + 628, 628, 628, 628, 914, 914, 615, 615, + 615, 615, 615, 628, 628, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 615, 615, 615, 615, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 6429, 6430, 6431, 6432, 6433, 6434, + 6435, 6436, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 77, 77, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 615, 615, 615, 77, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6437, 6438, 6439, 6440, 6441, 6442, 6443, + 6444, 6445, 6446, 6447, 6448, 6449, 6450, 6451, + 6452, 6453, 6454, 6455, 6456, 6457, 6458, 6459, + 6460, 6461, 6462, 6463, 6464, 6465, 6466, 6467, + 6468, 6469, 6470, 6471, 6472, 6473, 6474, 6475, + 6476, 6477, 6478, 6479, 6480, 6481, 6482, 6483, + 6484, 6485, 6486, 6487, 6488, 6489, 6490, 6491, + 6492, 6493, 6494, 6495, 6496, 6497, 6498, 6499, + 6500, 6501, 6502, 6503, 6504, 6505, 6506, 6507, + 6508, 6509, 6510, 6511, 6512, 6513, 6514, 6515, + 6516, 6517, 6518, 6519, 6520, 6521, 0, 6522, + 6523, 6524, 6525, 6526, 6527, 6528, 6529, 6530, + 6531, 6532, 6533, 6534, 6535, 6536, 6537, 6538, + 6539, 6540, 6541, 6542, 6543, 6544, 6545, 6546, + 6547, 6548, 6549, 6550, 6551, 6552, 6553, 6554, + 6555, 6556, 6557, 6558, 6559, 6560, 6561, 6562, + 6563, 6564, 6565, 6566, 6567, 6568, 6569, 6570, + 6571, 6572, 6573, 6574, 6575, 6576, 6577, 6578, + 6579, 6580, 6581, 6582, 6583, 6584, 6585, 6586, + 6587, 6588, 6589, 6590, 6591, 6592, 0, 6593, + 6594, 0, 0, 6595, 0, 0, 6596, 6597, + 0, 0, 6598, 6599, 6600, 6601, 0, 6602, + 6603, 6604, 6605, 6606, 6607, 6608, 6609, 6610, + 6611, 6612, 6613, 0, 6614, 0, 6615, 6616, + 6617, 6618, 6619, 6620, 6621, 0, 6622, 6623, + 6624, 6625, 6626, 6627, 6628, 6629, 6630, 6631, + 6632, 6633, 6634, 6635, 6636, 6637, 6638, 6639, + 6640, 6641, 6642, 6643, 6644, 6645, 6646, 6647, + 6648, 6649, 6650, 6651, 6652, 6653, 6654, 6655, + 6656, 6657, 6658, 6659, 6660, 6661, 6662, 6663, + 6664, 6665, 6666, 6667, 6668, 6669, 6670, 6671, + 6672, 6673, 6674, 6675, 6676, 6677, 6678, 6679, + 6680, 6681, 6682, 6683, 6684, 6685, 6686, 0, + 6687, 6688, 6689, 6690, 0, 0, 6691, 6692, + 6693, 6694, 6695, 6696, 6697, 6698, 0, 6699, + 6700, 6701, 6702, 6703, 6704, 6705, 0, 6706, + 6707, 6708, 6709, 6710, 6711, 6712, 6713, 6714, + 6715, 6716, 6717, 6718, 6719, 6720, 6721, 6722, + 6723, 6724, 6725, 6726, 6727, 6728, 6729, 6730, + 6731, 6732, 6733, 0, 6734, 6735, 6736, 6737, + 0, 6738, 6739, 6740, 6741, 6742, 0, 6743, + 0, 0, 0, 6744, 6745, 6746, 6747, 6748, + 6749, 6750, 0, 6751, 6752, 6753, 6754, 6755, + 6756, 6757, 6758, 6759, 6760, 6761, 6762, 6763, + 6764, 6765, 6766, 6767, 6768, 6769, 6770, 6771, + 6772, 6773, 6774, 6775, 6776, 6777, 6778, 6779, + 6780, 6781, 6782, 6783, 6784, 6785, 6786, 6787, + 6788, 6789, 6790, 6791, 6792, 6793, 6794, 6795, + 6796, 6797, 6798, 6799, 6800, 6801, 6802, 6803, + 6804, 6805, 6806, 6807, 6808, 6809, 6810, 6811, + 6812, 6813, 6814, 6815, 6816, 6817, 6818, 6819, + 6820, 6821, 6822, 6823, 6824, 6825, 6826, 6827, + 6828, 6829, 6830, 6831, 6832, 6833, 6834, 6835, + 6836, 6837, 6838, 6839, 6840, 6841, 6842, 6843, + 6844, 6845, 6846, 6847, 6848, 6849, 6850, 6851, + 6852, 6853, 6854, 6855, 6856, 6857, 6858, 6859, + 6860, 6861, 6862, 6863, 6864, 6865, 6866, 6867, + 6868, 6869, 6870, 6871, 6872, 6873, 6874, 6875, + 6876, 6877, 6878, 6879, 6880, 6881, 6882, 6883, + 6884, 6885, 6886, 6887, 6888, 6889, 6890, 6891, + 6892, 6893, 6894, 6895, 6896, 6897, 6898, 6899, + 6900, 6901, 6902, 6903, 6904, 6905, 6906, 6907, + 6908, 6909, 6910, 6911, 6912, 6913, 6914, 6915, + 6916, 6917, 6918, 6919, 6920, 6921, 6922, 6923, + 6924, 6925, 6926, 6927, 6928, 6929, 6930, 6931, + 6932, 6933, 6934, 6935, 6936, 6937, 6938, 6939, + 6940, 6941, 6942, 6943, 6944, 6945, 6946, 6947, + 6948, 6949, 6950, 6951, 6952, 6953, 6954, 6955, + 6956, 6957, 6958, 6959, 6960, 6961, 6962, 6963, + 6964, 6965, 6966, 6967, 6968, 6969, 6970, 6971, + 6972, 6973, 6974, 6975, 6976, 6977, 6978, 6979, + 6980, 6981, 6982, 6983, 6984, 6985, 6986, 6987, + 6988, 6989, 6990, 6991, 6992, 6993, 6994, 6995, + 6996, 6997, 6998, 6999, 7000, 7001, 7002, 7003, + 7004, 7005, 7006, 7007, 7008, 7009, 7010, 7011, + 7012, 7013, 7014, 7015, 7016, 7017, 7018, 7019, + 7020, 7021, 7022, 7023, 7024, 7025, 7026, 7027, + 7028, 7029, 7030, 7031, 7032, 7033, 7034, 7035, + 7036, 7037, 7038, 7039, 7040, 7041, 7042, 7043, + 7044, 7045, 7046, 7047, 7048, 7049, 7050, 7051, + 7052, 7053, 7054, 7055, 7056, 7057, 7058, 7059, + 7060, 7061, 7062, 7063, 7064, 7065, 7066, 7067, + 7068, 7069, 7070, 7071, 7072, 7073, 7074, 7075, + 7076, 7077, 7078, 7079, 7080, 7081, 7082, 7083, + 7084, 7085, 7086, 7087, 7088, 7089, 7090, 0, + 0, 7091, 7092, 7093, 7094, 7095, 7096, 7097, + 7098, 7099, 7100, 7101, 7102, 7103, 7104, 7105, + 7106, 7107, 7108, 7109, 7110, 7111, 7112, 7113, + 7114, 7115, 7116, 7117, 7118, 7119, 7120, 7121, + 7122, 7123, 7124, 7125, 7126, 7127, 7128, 7129, + 7130, 7131, 7132, 7133, 7134, 7135, 7136, 7137, + 7138, 7139, 7140, 7141, 7142, 7143, 7144, 7145, + 7146, 7147, 7148, 7149, 7150, 7151, 7152, 7153, + 7154, 7155, 7156, 7157, 7158, 7159, 7160, 7161, + 7162, 7163, 7164, 7165, 7166, 7167, 7168, 7169, + 7170, 7171, 7172, 7173, 7116, 7174, 7175, 7176, + 7177, 7178, 7179, 7180, 7181, 7182, 7183, 7184, + 7185, 7186, 7187, 7188, 7189, 7190, 7191, 7192, + 7193, 7194, 7195, 7196, 7197, 7198, 7142, 7199, + 7200, 7201, 7202, 7203, 7204, 7205, 7206, 7207, + 7208, 7209, 7210, 7211, 7212, 7213, 7214, 7215, + 7216, 7217, 7218, 7219, 7220, 7221, 7222, 7223, + 7224, 7225, 7226, 7227, 7228, 7229, 7116, 7230, + 7231, 7232, 7233, 7234, 7235, 7236, 7237, 7238, + 7239, 7240, 7241, 7242, 7243, 7244, 7245, 7246, + 7247, 7248, 7249, 7250, 7251, 7252, 7253, 7254, + 7142, 7255, 7256, 7257, 7258, 7259, 7260, 7261, + 7262, 7263, 7264, 7265, 7266, 7267, 7268, 7269, + 7270, 7271, 7272, 7273, 7274, 7275, 7276, 7277, + 7278, 7279, 7280, 7281, 7282, 7283, 7284, 7285, + 7116, 7286, 7287, 7288, 7289, 7290, 7291, 7292, + 7293, 7294, 7295, 7296, 7297, 7298, 7299, 7300, + 7301, 7302, 7303, 7304, 7305, 7306, 7307, 7308, + 7309, 7310, 7142, 7311, 7312, 7313, 7314, 7315, + 7316, 7317, 7318, 7319, 7320, 7321, 7322, 7323, + 7324, 7325, 7326, 7327, 7328, 7329, 7330, 7331, + 7332, 7333, 7334, 7335, 7336, 7337, 7338, 7339, + 7340, 7341, 7116, 7342, 7343, 7344, 7345, 7346, + 7347, 7348, 7349, 7350, 7351, 7352, 7353, 7354, + 7355, 7356, 7357, 7358, 7359, 7360, 7361, 7362, + 7363, 7364, 7365, 7366, 7142, 7367, 7368, 7369, + 7370, 7371, 7372, 7373, 7374, 0, 0, 7375, + 7376, 7377, 7378, 7379, 7380, 7381, 7382, 7383, + 7384, 7375, 7376, 7377, 7378, 7379, 7380, 7381, + 7382, 7383, 7384, 7375, 7376, 7377, 7378, 7379, + 7380, 7381, 7382, 7383, 7384, 7375, 7376, 7377, + 7378, 7379, 7380, 7381, 7382, 7383, 7384, 7375, + 7376, 7377, 7378, 7379, 7380, 7381, 7382, 7383, + 7384, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 914, 914, 914, 914, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 914, 914, + 914, 914, 914, 914, 914, 914, 1226, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 1226, 914, 914, + 1120, 1120, 1120, 1120, 1120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1226, 1226, 1226, 1226, + 1226, 0, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1226, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7385, 7386, 7387, 7388, 7389, 7390, 7391, + 7392, 7393, 7394, 346, 7395, 7396, 7397, 7398, + 7399, 7400, 7401, 7402, 7403, 7404, 7405, 7406, + 7407, 7408, 7409, 7410, 7411, 7412, 7413, 7414, + 0, 0, 0, 0, 0, 0, 7415, 7416, + 7417, 7418, 7419, 7420, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 615, 615, 615, 615, 615, 615, 615, + 0, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 0, 0, 615, 615, 615, 615, + 615, 615, 615, 0, 615, 615, 0, 615, + 615, 615, 615, 615, 0, 0, 0, 0, + 0, 7421, 7422, 7423, 7424, 7425, 7426, 7427, + 7428, 7429, 7430, 7431, 7432, 7433, 7434, 7435, + 7436, 7437, 7438, 7439, 7440, 7441, 7442, 7443, + 7444, 7445, 7446, 7447, 7448, 7449, 7450, 7451, + 7452, 7453, 7454, 7455, 7456, 7457, 7458, 7459, + 7460, 7461, 7462, 7463, 7464, 7465, 7466, 7467, + 7468, 7469, 7470, 7471, 7472, 7473, 7474, 7475, + 7476, 7477, 7478, 7479, 7480, 7481, 7482, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 615, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 0, 0, + 0, 615, 615, 615, 615, 615, 615, 615, + 596, 596, 596, 596, 596, 596, 596, 0, + 0, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 346, + 914, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 615, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 615, 615, 615, + 615, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 596, 627, 627, 628, + 615, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 346, 346, 346, 346, 346, 346, 346, + 0, 346, 346, 346, 346, 0, 346, 346, + 0, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 0, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 0, 0, + 6141, 6141, 6141, 6141, 6141, 6141, 6141, 6141, + 6141, 628, 628, 628, 628, 628, 628, 628, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7483, 7484, 7485, 7486, 7487, 7488, 7489, + 7490, 7491, 7492, 7493, 7494, 7495, 7496, 7497, + 7498, 7499, 7500, 7501, 7502, 7503, 7504, 7505, + 7506, 7507, 7508, 7509, 7510, 7511, 7512, 7513, + 7514, 7515, 7516, 7517, 7518, 7519, 7520, 7521, + 7522, 7523, 7524, 7525, 7526, 7527, 7528, 7529, + 7530, 7531, 7532, 7533, 7534, 7535, 7536, 7537, + 7538, 7539, 7540, 7541, 7542, 7543, 7544, 7545, + 7546, 7547, 7548, 7549, 7550, 615, 615, 615, + 615, 615, 615, 1249, 1228, 0, 0, 0, + 0, 1227, 1227, 1227, 1227, 1227, 1227, 1227, + 1227, 1227, 1227, 0, 0, 0, 0, 1180, + 1180, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 1223, 6246, 6246, + 6246, 1186, 6246, 6246, 6246, 6246, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 1223, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 6246, + 6246, 6246, 6246, 6246, 6246, 6246, 6246, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7551, 7552, 7553, 7554, 0, 7555, 7556, + 7557, 7558, 7559, 7560, 7561, 7562, 7563, 7564, + 7565, 7566, 7567, 7568, 7569, 7570, 7571, 7572, + 7573, 7574, 7575, 7576, 7577, 7578, 7579, 7580, + 7581, 0, 7552, 7553, 0, 7582, 0, 0, + 7557, 0, 7559, 7560, 7561, 7562, 7563, 7564, + 7565, 7566, 7567, 7568, 0, 7570, 7571, 7572, + 7573, 0, 7575, 0, 7577, 0, 0, 0, + 0, 0, 0, 7553, 0, 0, 0, 0, + 7557, 0, 7559, 0, 7561, 0, 7563, 7564, + 7565, 0, 7567, 7568, 0, 7570, 0, 0, + 7573, 0, 7575, 0, 7577, 0, 7579, 0, + 7581, 0, 7552, 7553, 0, 7582, 0, 0, + 7557, 7558, 7559, 7560, 0, 7562, 7563, 7564, + 7565, 7566, 7567, 7568, 0, 7570, 7571, 7572, + 7573, 0, 7575, 7576, 7577, 7578, 0, 7580, + 0, 7551, 7552, 7553, 7554, 7582, 7555, 7556, + 7557, 7558, 7559, 0, 7561, 7562, 7563, 7564, + 7565, 7566, 7567, 7568, 7569, 7570, 7571, 7572, + 7573, 7574, 7575, 7576, 7577, 0, 0, 0, + 0, 0, 7552, 7553, 7554, 0, 7555, 7556, + 7557, 7558, 7559, 0, 7561, 7562, 7563, 7564, + 7565, 7566, 7567, 7568, 7569, 7570, 7571, 7572, + 7573, 7574, 7575, 7576, 7577, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 75, 75, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 79, 79, 79, 79, 2577, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 0, 0, 0, + 0, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 0, 0, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 0, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 2577, 0, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7583, 7584, 7585, 7586, 7587, 7588, 7589, + 7590, 7591, 7592, 7593, 1287, 1287, 79, 79, + 79, 7594, 7595, 7596, 7597, 7598, 7599, 7600, + 7601, 7602, 7603, 7604, 7605, 7606, 7607, 7608, + 7609, 7610, 7611, 7612, 7613, 7614, 7615, 7616, + 7617, 7618, 7619, 7620, 7621, 7622, 7623, 7624, + 79, 7625, 7626, 7627, 7628, 7629, 7630, 7631, + 7632, 7633, 7634, 7635, 7636, 7637, 7638, 7639, + 7640, 7641, 7642, 7643, 7644, 7645, 7646, 7647, + 7648, 7649, 7650, 7651, 7652, 7653, 7654, 7655, + 7656, 7657, 7658, 7659, 7660, 7661, 7662, 7663, + 7664, 7665, 7666, 7667, 7668, 7669, 7670, 7671, + 7672, 7673, 7674, 7675, 7676, 7677, 7678, 7679, + 7680, 7681, 7682, 7683, 7684, 7685, 79, 79, + 79, 7686, 7687, 7688, 7689, 7690, 7691, 7692, + 7693, 7694, 7695, 7696, 7697, 7698, 7699, 7700, + 7701, 7702, 7703, 7704, 7705, 7706, 7707, 7708, + 7709, 7710, 7711, 914, 914, 914, 914, 7712, + 914, 7713, 7712, 7712, 7712, 7712, 7712, 7712, + 7712, 7712, 7712, 7712, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 914, 79, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7714, + 7714, 7714, 7714, 7714, 7714, 7714, 7714, 7714, + 7714, 7714, 7714, 7714, 7714, 7714, 7714, 7714, + 7714, 7714, 7714, 7714, 7714, 7714, 7714, 7714, + 7714, 7715, 7716, 7717, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7718, 7719, 7720, 7721, 7722, 7723, 7724, + 7725, 7726, 7727, 7728, 7729, 7730, 7731, 7732, + 7733, 7734, 7735, 7736, 7737, 7738, 7739, 7740, + 7741, 7742, 7743, 7744, 7745, 7746, 7747, 7748, + 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756, + 7757, 7758, 7759, 7760, 7761, 0, 0, 0, + 0, 7762, 7763, 7764, 7765, 7766, 7767, 7768, + 7769, 7770, 0, 0, 0, 0, 0, 0, + 0, 7771, 7772, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2577, 2577, 2577, 2577, 2577, 2577, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 79, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 79, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 79, 79, 79, 79, + 2577, 2577, 2577, 2577, 2577, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 79, 79, 79, 2577, 79, 79, + 79, 2577, 2577, 2577, 7773, 7773, 7773, 7773, + 7773, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 79, 2577, 79, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 79, 79, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 77, + 77, 77, 77, 77, 77, 77, 77, 79, + 79, 79, 79, 79, 2577, 2577, 2577, 2577, + 79, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 2577, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 2577, 2577, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 2577, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 79, + 79, 79, 79, 79, 79, 2577, 79, 79, + 79, 2577, 2577, 2577, 79, 79, 2577, 2577, + 2577, 0, 0, 0, 0, 2577, 2577, 2577, + 2577, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 2577, 2577, 0, 0, + 0, 79, 79, 79, 79, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 79, 79, 79, + 0, 0, 0, 0, 79, 79, 79, 79, + 79, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 79, 79, + 79, 79, 79, 0, 0, 0, 0, 0, + 0, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 0, 0, 0, + 0, 2577, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 0, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 0, 0, 0, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 0, + 0, 79, 79, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 77, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 77, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 0, + 0, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 0, 0, + 0, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 0, 0, 0, 0, 0, 0, + 0, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 0, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 0, + 0, 0, 0, 0, 0, 0, 0, 2577, + 2577, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 2577, 2577, 2577, 0, 0, 0, + 0, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 0, 0, 0, 0, 0, 0, + 0, 2577, 2577, 2577, 2577, 2577, 2577, 2577, + 2577, 2577, 0, 0, 0, 0, 0, 0, + 0, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 0, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7375, 7376, 7377, 7378, 7379, 7380, 7381, + 7382, 7383, 7384, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7774, 7775, 7776, 7777, 7778, 4647, 7779, + 7780, 7781, 7782, 4648, 7783, 7784, 7785, 4649, + 7786, 7787, 7788, 7789, 7790, 7791, 7792, 7793, + 7794, 7795, 7796, 7797, 4707, 7798, 7799, 7800, + 7801, 7802, 7803, 7804, 7805, 7806, 4712, 4650, + 4651, 4713, 7807, 7808, 4458, 7809, 4652, 7810, + 7811, 7812, 7813, 7813, 7813, 7814, 7815, 7816, + 7817, 7818, 7819, 7820, 7821, 7822, 7823, 7824, + 7825, 7826, 7827, 7828, 7829, 7830, 7831, 7831, + 4715, 7832, 7833, 7834, 7835, 4654, 7836, 7837, + 7838, 4611, 7839, 7840, 7841, 7842, 7843, 7844, + 7845, 7846, 7847, 7848, 7849, 7850, 7851, 7852, + 7853, 7854, 7855, 7856, 7857, 7858, 7859, 7860, + 7861, 7862, 7863, 7864, 7864, 7865, 7866, 7867, + 4454, 7868, 7869, 7870, 7871, 7872, 7873, 7874, + 7875, 4659, 7876, 7877, 7878, 7879, 7880, 7881, + 7882, 7883, 7884, 7885, 7886, 7887, 7888, 7889, + 7890, 7891, 7892, 7893, 7894, 7895, 7896, 4400, + 7897, 7898, 7899, 7899, 7900, 7901, 7901, 7902, + 7903, 7904, 7905, 7906, 7907, 7908, 7909, 7910, + 7911, 7912, 7913, 7914, 4660, 7915, 7916, 7917, + 7918, 4727, 7918, 7919, 4662, 7920, 7921, 7922, + 7923, 4663, 4373, 7924, 7925, 7926, 7927, 7928, + 7929, 7930, 7931, 7932, 7933, 7934, 7935, 7936, + 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7944, + 7945, 4664, 7946, 7947, 7948, 7949, 7950, 7951, + 4666, 7952, 7953, 7954, 7955, 7956, 7957, 7958, + 7959, 4401, 4735, 7960, 7961, 7962, 7963, 7964, + 7965, 7966, 7967, 4667, 7968, 7969, 7970, 7971, + 4778, 7972, 7973, 7974, 7975, 7976, 7977, 7978, + 7979, 7980, 7981, 7982, 7983, 7984, 4471, 7985, + 7986, 7987, 7988, 7989, 7990, 7991, 7992, 7993, + 7994, 7995, 4668, 4558, 7996, 7997, 7998, 7999, + 8000, 8001, 8002, 8003, 4739, 8004, 8005, 8006, + 8007, 8008, 8009, 8010, 8011, 4740, 8012, 8013, + 8014, 8015, 8016, 8017, 8018, 8019, 8020, 8021, + 8022, 8023, 4742, 8024, 8025, 8026, 8027, 8028, + 8029, 8030, 8031, 8032, 8033, 8034, 8034, 8035, + 8036, 4744, 8037, 8038, 8039, 8040, 8041, 8042, + 8043, 4457, 8044, 8045, 8046, 8047, 8048, 8049, + 8050, 4750, 8051, 8052, 8053, 8054, 8055, 8056, + 8056, 4751, 4780, 8057, 8058, 8059, 8060, 8061, + 4419, 4753, 8062, 8063, 4679, 8064, 8065, 4633, + 8066, 8067, 4683, 8068, 8069, 8070, 8071, 8071, + 8072, 8073, 8074, 8075, 8076, 8077, 8078, 8079, + 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, + 8088, 8089, 8090, 8091, 8092, 8093, 8094, 8095, + 8096, 8097, 8098, 4689, 8099, 8100, 8101, 8102, + 8103, 8104, 8105, 8106, 8107, 8108, 8109, 8110, + 8111, 8112, 8113, 8114, 7900, 8115, 8116, 8117, + 8118, 8119, 8120, 8121, 8122, 8123, 8124, 8125, + 8126, 4475, 8127, 8128, 8129, 8130, 8131, 8132, + 4692, 8133, 8134, 8135, 8136, 8137, 8138, 8139, + 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, + 8148, 8149, 8150, 8151, 8152, 4414, 8153, 8154, + 8155, 8156, 8157, 8158, 4760, 8159, 8160, 8161, + 8162, 8163, 8164, 8165, 8166, 8167, 8168, 8169, + 8170, 8171, 8172, 8173, 8174, 8175, 8176, 8177, + 8178, 4765, 4766, 8179, 8180, 8181, 8182, 8183, + 8184, 8185, 8186, 8187, 8188, 8189, 8190, 8191, + 4767, 8192, 8193, 8194, 8195, 8196, 8197, 8198, + 8199, 8200, 8201, 8202, 8203, 8204, 8205, 8206, + 8207, 8208, 8209, 8210, 8211, 8212, 8213, 8214, + 8215, 8216, 8217, 8218, 8219, 8220, 8221, 4773, + 4773, 8222, 8223, 8224, 8225, 8226, 8227, 8228, + 8229, 8230, 8231, 4774, 8232, 8233, 8234, 8235, + 8236, 8237, 8238, 8239, 8240, 8241, 8242, 8243, + 8244, 8245, 8246, 8247, 8248, 8249, 8250, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 0, 0, 0, 0, + 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, + 3225, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1536, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, + 2301, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, + 649, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 0, + 0, }; + +static const utf8proc_property_t utf8proc_properties[] = { + {0, 0, 0, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false,false,false,false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_S, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_B, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_LF}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_WS, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_B, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CR}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_B, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5093, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5084, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5096, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX, 0, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1, UINT16_MAX, 1, UINT16_MAX, 2784, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2, UINT16_MAX, 2, UINT16_MAX, 49, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3, UINT16_MAX, 3, UINT16_MAX, 704, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 4, UINT16_MAX, 4, UINT16_MAX, 62, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5, UINT16_MAX, 5, UINT16_MAX, 2872, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6, UINT16_MAX, 6, UINT16_MAX, 782, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7, UINT16_MAX, 7, UINT16_MAX, 808, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 8, UINT16_MAX, 8, UINT16_MAX, 111, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 9, UINT16_MAX, 9, UINT16_MAX, 898, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 10, UINT16_MAX, 10, UINT16_MAX, 913, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 11, UINT16_MAX, 11, UINT16_MAX, 999, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 12, UINT16_MAX, 12, UINT16_MAX, 2890, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 13, UINT16_MAX, 13, UINT16_MAX, 160, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 14, UINT16_MAX, 14, UINT16_MAX, 205, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 15, UINT16_MAX, 15, UINT16_MAX, 2982, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 16, UINT16_MAX, 16, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 17, UINT16_MAX, 17, UINT16_MAX, 1087, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 18, UINT16_MAX, 18, UINT16_MAX, 1173, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 19, UINT16_MAX, 19, UINT16_MAX, 1257, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 20, UINT16_MAX, 20, UINT16_MAX, 254, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 21, UINT16_MAX, 21, UINT16_MAX, 3042, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 22, UINT16_MAX, 22, UINT16_MAX, 1337, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 23, UINT16_MAX, 23, UINT16_MAX, 3122, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 24, UINT16_MAX, 24, UINT16_MAX, 303, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 25, UINT16_MAX, 25, UINT16_MAX, 1423, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1491, UINT16_MAX, 1491, 352, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1493, UINT16_MAX, 1493, 2818, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2813, UINT16_MAX, 2813, 401, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1494, UINT16_MAX, 1494, 743, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1495, UINT16_MAX, 1495, 414, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2838, UINT16_MAX, 2838, 2875, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1497, UINT16_MAX, 1497, 795, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1498, UINT16_MAX, 1498, 853, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1499, UINT16_MAX, 1499, 463, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1500, UINT16_MAX, 1500, 901, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1501, UINT16_MAX, 1501, 956, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1502, UINT16_MAX, 1502, 1043, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1503, UINT16_MAX, 1503, 2932, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1504, UINT16_MAX, 1504, 512, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1505, UINT16_MAX, 1505, 557, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1507, UINT16_MAX, 1507, 2994, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2827, UINT16_MAX, 2827, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1508, UINT16_MAX, 1508, 1130, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 3320, UINT16_MAX, 3320, 1215, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1509, UINT16_MAX, 1509, 1296, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1510, UINT16_MAX, 1510, 606, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2910, UINT16_MAX, 2910, 3082, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1511, UINT16_MAX, 1511, 1380, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2928, UINT16_MAX, 2928, 3131, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 3327, UINT16_MAX, 3327, 655, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2835, UINT16_MAX, 2835, 1466, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_NOBREAK, 26, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 16411, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 1621, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 0, UINT16_MAX, 8289, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PI, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 1, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 16413, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ET, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ET, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 31, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 32, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 16417, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35, 35, 7440, UINT16_MAX, 7440, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 16420, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 38, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 14, UINT16_MAX, 8290, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PF, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 32807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 32810, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 32813, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16432, 50, UINT16_MAX, 50, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16435, 53, UINT16_MAX, 53, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16438, 56, UINT16_MAX, 56, UINT16_MAX, 3143, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16441, 59, UINT16_MAX, 59, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16444, 62, UINT16_MAX, 62, UINT16_MAX, 1537, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16447, 65, UINT16_MAX, 65, UINT16_MAX, 1579, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 66, UINT16_MAX, 66, UINT16_MAX, 1549, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16451, 69, UINT16_MAX, 69, UINT16_MAX, 2852, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16454, 72, UINT16_MAX, 72, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16457, 75, UINT16_MAX, 75, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16460, 78, UINT16_MAX, 78, UINT16_MAX, 3357, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16463, 81, UINT16_MAX, 81, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16466, 84, UINT16_MAX, 84, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16469, 87, UINT16_MAX, 87, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16472, 90, UINT16_MAX, 90, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16475, 93, UINT16_MAX, 93, UINT16_MAX, 2878, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 94, UINT16_MAX, 94, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16479, 97, UINT16_MAX, 97, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16482, 100, UINT16_MAX, 100, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16485, 103, UINT16_MAX, 103, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16488, 106, UINT16_MAX, 106, UINT16_MAX, 3461, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16491, 109, UINT16_MAX, 109, UINT16_MAX, 1597, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16494, 112, UINT16_MAX, 112, UINT16_MAX, 1591, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 113, UINT16_MAX, 113, UINT16_MAX, 1585, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16498, 116, UINT16_MAX, 116, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16501, 119, UINT16_MAX, 119, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16504, 122, UINT16_MAX, 122, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16507, 125, UINT16_MAX, 125, UINT16_MAX, 1509, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16510, 128, UINT16_MAX, 128, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 129, UINT16_MAX, 129, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 16514, 8291, UINT16_MAX, 8291, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16516, UINT16_MAX, 8292, UINT16_MAX, 8292, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16518, UINT16_MAX, 8293, UINT16_MAX, 8293, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16520, UINT16_MAX, 8294, UINT16_MAX, 8294, 3192, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16522, UINT16_MAX, 8295, UINT16_MAX, 8295, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16524, UINT16_MAX, 8296, UINT16_MAX, 8296, 1540, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16526, UINT16_MAX, 2837, UINT16_MAX, 2837, 1582, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1492, UINT16_MAX, 1492, 1558, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16528, UINT16_MAX, 8297, UINT16_MAX, 8297, 2855, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16530, UINT16_MAX, 8298, UINT16_MAX, 8298, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16532, UINT16_MAX, 8299, UINT16_MAX, 8299, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16534, UINT16_MAX, 8300, UINT16_MAX, 8300, 3406, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16536, UINT16_MAX, 8301, UINT16_MAX, 8301, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16538, UINT16_MAX, 8302, UINT16_MAX, 8302, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16540, UINT16_MAX, 8303, UINT16_MAX, 8303, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16542, UINT16_MAX, 8304, UINT16_MAX, 8304, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16544, UINT16_MAX, 8305, UINT16_MAX, 8305, 2881, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8306, UINT16_MAX, 8306, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16546, UINT16_MAX, 8307, UINT16_MAX, 8307, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16548, UINT16_MAX, 8308, UINT16_MAX, 8308, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16550, UINT16_MAX, 8309, UINT16_MAX, 8309, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16552, UINT16_MAX, 8310, UINT16_MAX, 8310, 3510, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16554, UINT16_MAX, 8311, UINT16_MAX, 8311, 1606, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16556, UINT16_MAX, 8312, UINT16_MAX, 8312, 1594, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8313, UINT16_MAX, 8313, 1588, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16558, UINT16_MAX, 8314, UINT16_MAX, 8314, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16560, UINT16_MAX, 8315, UINT16_MAX, 8315, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16562, UINT16_MAX, 8316, UINT16_MAX, 8316, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16564, UINT16_MAX, 8317, UINT16_MAX, 8317, 1523, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16566, UINT16_MAX, 8318, UINT16_MAX, 8318, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8319, UINT16_MAX, 8319, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16568, UINT16_MAX, 8320, UINT16_MAX, 8320, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16570, 188, UINT16_MAX, 188, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16573, UINT16_MAX, 8321, UINT16_MAX, 8321, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16575, 193, UINT16_MAX, 193, UINT16_MAX, 3259, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16578, UINT16_MAX, 8322, UINT16_MAX, 8322, 3308, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16580, 198, UINT16_MAX, 198, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16583, UINT16_MAX, 8323, UINT16_MAX, 8323, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16585, 203, UINT16_MAX, 203, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16588, UINT16_MAX, 8324, UINT16_MAX, 8324, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16590, 208, UINT16_MAX, 208, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16593, UINT16_MAX, 8325, UINT16_MAX, 8325, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16595, 213, UINT16_MAX, 213, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16598, UINT16_MAX, 8326, UINT16_MAX, 8326, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16600, 218, UINT16_MAX, 218, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16603, UINT16_MAX, 8327, UINT16_MAX, 8327, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16605, 223, UINT16_MAX, 223, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16608, UINT16_MAX, 8328, UINT16_MAX, 8328, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 226, UINT16_MAX, 226, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8329, UINT16_MAX, 8329, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16611, 229, UINT16_MAX, 229, UINT16_MAX, 2858, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16614, UINT16_MAX, 8330, UINT16_MAX, 8330, 2862, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16616, 234, UINT16_MAX, 234, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16619, UINT16_MAX, 8331, UINT16_MAX, 8331, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16621, 239, UINT16_MAX, 239, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16624, UINT16_MAX, 8332, UINT16_MAX, 8332, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16626, 244, UINT16_MAX, 244, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16629, UINT16_MAX, 8333, UINT16_MAX, 8333, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16631, 249, UINT16_MAX, 249, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16634, UINT16_MAX, 8334, UINT16_MAX, 8334, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16636, 254, UINT16_MAX, 254, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16639, UINT16_MAX, 8335, UINT16_MAX, 8335, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16641, 259, UINT16_MAX, 259, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16644, UINT16_MAX, 8336, UINT16_MAX, 8336, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16646, 264, UINT16_MAX, 264, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16649, UINT16_MAX, 8337, UINT16_MAX, 8337, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16651, 269, UINT16_MAX, 269, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16654, UINT16_MAX, 8338, UINT16_MAX, 8338, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16656, 274, UINT16_MAX, 274, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16659, UINT16_MAX, 8339, UINT16_MAX, 8339, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 277, UINT16_MAX, 277, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 5251, UINT16_MAX, 5251, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16662, 280, UINT16_MAX, 280, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16665, UINT16_MAX, 8340, UINT16_MAX, 8340, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16667, 285, UINT16_MAX, 285, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16670, UINT16_MAX, 8341, UINT16_MAX, 8341, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16672, 290, UINT16_MAX, 290, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16675, UINT16_MAX, 8342, UINT16_MAX, 8342, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16677, 295, UINT16_MAX, 295, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16680, UINT16_MAX, 8343, UINT16_MAX, 8343, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16682, 16684, UINT16_MAX, 8, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1499, UINT16_MAX, 1499, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16686, 304, UINT16_MAX, 304, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16689, UINT16_MAX, 8344, UINT16_MAX, 8344, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16691, 309, UINT16_MAX, 309, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16694, UINT16_MAX, 8345, UINT16_MAX, 8345, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16696, 314, UINT16_MAX, 314, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16699, UINT16_MAX, 8346, UINT16_MAX, 8346, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8347, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16701, 319, UINT16_MAX, 319, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16704, UINT16_MAX, 8348, UINT16_MAX, 8348, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16706, 324, UINT16_MAX, 324, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16709, UINT16_MAX, 8349, UINT16_MAX, 8349, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16711, 329, UINT16_MAX, 329, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16714, UINT16_MAX, 8350, UINT16_MAX, 8350, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16716, 334, UINT16_MAX, 334, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16719, UINT16_MAX, 8351, UINT16_MAX, 8351, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 337, UINT16_MAX, 337, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8352, UINT16_MAX, 8352, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16722, 340, UINT16_MAX, 340, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16725, UINT16_MAX, 8353, UINT16_MAX, 8353, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16727, 345, UINT16_MAX, 345, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16730, UINT16_MAX, 8354, UINT16_MAX, 8354, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16732, 350, UINT16_MAX, 350, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16735, UINT16_MAX, 8355, UINT16_MAX, 8355, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16737, 16737, 8356, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 355, UINT16_MAX, 355, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8357, UINT16_MAX, 8357, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16740, 358, UINT16_MAX, 358, UINT16_MAX, 2974, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16743, UINT16_MAX, 8358, UINT16_MAX, 8358, 2978, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16745, 363, UINT16_MAX, 363, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16748, UINT16_MAX, 8359, UINT16_MAX, 8359, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16750, 368, UINT16_MAX, 368, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16753, UINT16_MAX, 8360, UINT16_MAX, 8360, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 371, UINT16_MAX, 371, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8361, UINT16_MAX, 8361, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16756, 374, UINT16_MAX, 374, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16759, UINT16_MAX, 8362, UINT16_MAX, 8362, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16761, 379, UINT16_MAX, 379, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16764, UINT16_MAX, 8363, UINT16_MAX, 8363, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16766, 384, UINT16_MAX, 384, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16769, UINT16_MAX, 8364, UINT16_MAX, 8364, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16771, 389, UINT16_MAX, 389, UINT16_MAX, 3012, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16774, UINT16_MAX, 8365, UINT16_MAX, 8365, 3015, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16776, 394, UINT16_MAX, 394, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16779, UINT16_MAX, 8366, UINT16_MAX, 8366, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16781, 399, UINT16_MAX, 399, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16784, UINT16_MAX, 8367, UINT16_MAX, 8367, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16786, 404, UINT16_MAX, 404, UINT16_MAX, 3018, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16789, UINT16_MAX, 8368, UINT16_MAX, 8368, 3021, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16791, 409, UINT16_MAX, 409, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16794, UINT16_MAX, 8369, UINT16_MAX, 8369, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16796, 414, UINT16_MAX, 414, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16799, UINT16_MAX, 8370, UINT16_MAX, 8370, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 417, UINT16_MAX, 417, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8371, UINT16_MAX, 8371, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16802, 420, UINT16_MAX, 420, UINT16_MAX, 3030, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16805, UINT16_MAX, 8372, UINT16_MAX, 8372, 3033, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16807, 425, UINT16_MAX, 425, UINT16_MAX, 3036, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16810, UINT16_MAX, 8373, UINT16_MAX, 8373, 3039, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16812, 430, UINT16_MAX, 430, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16815, UINT16_MAX, 8374, UINT16_MAX, 8374, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16817, 435, UINT16_MAX, 435, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16820, UINT16_MAX, 8375, UINT16_MAX, 8375, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16822, 440, UINT16_MAX, 440, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16825, UINT16_MAX, 8376, UINT16_MAX, 8376, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16827, 445, UINT16_MAX, 445, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16830, UINT16_MAX, 8377, UINT16_MAX, 8377, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16832, 450, UINT16_MAX, 450, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16835, UINT16_MAX, 8378, UINT16_MAX, 8378, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16837, 455, UINT16_MAX, 455, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16840, UINT16_MAX, 8379, UINT16_MAX, 8379, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16842, 460, UINT16_MAX, 460, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16845, 463, UINT16_MAX, 463, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16848, UINT16_MAX, 8380, UINT16_MAX, 8380, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16850, 468, UINT16_MAX, 468, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16853, UINT16_MAX, 8381, UINT16_MAX, 8381, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16855, 473, UINT16_MAX, 473, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16858, UINT16_MAX, 8382, UINT16_MAX, 8382, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 18, 18, 3320, UINT16_MAX, 3320, 3140, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8383, UINT16_MAX, 8383, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 476, UINT16_MAX, 476, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 477, UINT16_MAX, 477, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8384, UINT16_MAX, 8384, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 478, UINT16_MAX, 478, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8385, UINT16_MAX, 8385, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 479, UINT16_MAX, 479, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 480, UINT16_MAX, 480, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8386, UINT16_MAX, 8386, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 481, UINT16_MAX, 481, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 482, UINT16_MAX, 482, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 483, UINT16_MAX, 483, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8387, UINT16_MAX, 8387, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8388, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 484, UINT16_MAX, 484, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 485, UINT16_MAX, 485, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 486, UINT16_MAX, 486, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 487, UINT16_MAX, 487, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8389, UINT16_MAX, 8389, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 488, UINT16_MAX, 488, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 489, UINT16_MAX, 489, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8390, UINT16_MAX, 8390, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 490, UINT16_MAX, 490, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 491, UINT16_MAX, 491, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 492, UINT16_MAX, 492, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8391, UINT16_MAX, 8391, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8392, UINT16_MAX, 8392, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8393, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 493, UINT16_MAX, 493, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 494, UINT16_MAX, 494, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8394, UINT16_MAX, 8394, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 495, UINT16_MAX, 495, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16880, 498, UINT16_MAX, 498, UINT16_MAX, 3565, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16883, UINT16_MAX, 8395, UINT16_MAX, 8395, 3614, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 501, UINT16_MAX, 501, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8396, UINT16_MAX, 8396, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 502, UINT16_MAX, 502, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8397, UINT16_MAX, 8397, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 503, UINT16_MAX, 503, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 504, UINT16_MAX, 504, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8398, UINT16_MAX, 8398, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 505, UINT16_MAX, 505, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8399, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1537, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 506, UINT16_MAX, 506, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8400, UINT16_MAX, 8400, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 507, UINT16_MAX, 507, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16892, 510, UINT16_MAX, 510, UINT16_MAX, 3663, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16895, UINT16_MAX, 8401, UINT16_MAX, 8401, 3712, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 513, UINT16_MAX, 513, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 514, UINT16_MAX, 514, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 515, UINT16_MAX, 515, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8402, UINT16_MAX, 8402, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 516, UINT16_MAX, 516, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8403, UINT16_MAX, 8403, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 517, UINT16_MAX, 517, UINT16_MAX, 1573, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 518, UINT16_MAX, 518, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8404, UINT16_MAX, 8404, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8405, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 519, UINT16_MAX, 519, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8406, UINT16_MAX, 8406, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8407, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8408, UINT16_MAX, 8408, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16904, 522, UINT16_MAX, 522, 8409, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16907, 522, 8410, 522, 8409, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16909, UINT16_MAX, 8410, UINT16_MAX, 8409, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16911, 529, UINT16_MAX, 529, 8411, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16914, 529, 8412, 529, 8411, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16916, UINT16_MAX, 8412, UINT16_MAX, 8411, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16918, 536, UINT16_MAX, 536, 8413, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16921, 536, 8414, 536, 8413, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 16923, UINT16_MAX, 8414, UINT16_MAX, 8413, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16925, 543, UINT16_MAX, 543, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16928, UINT16_MAX, 8415, UINT16_MAX, 8415, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16930, 548, UINT16_MAX, 548, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16933, UINT16_MAX, 8416, UINT16_MAX, 8416, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16935, 553, UINT16_MAX, 553, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16938, UINT16_MAX, 8417, UINT16_MAX, 8417, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16940, 558, UINT16_MAX, 558, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16943, UINT16_MAX, 8418, UINT16_MAX, 8418, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16945, 563, UINT16_MAX, 563, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16948, UINT16_MAX, 8419, UINT16_MAX, 8419, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16950, 568, UINT16_MAX, 568, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16953, UINT16_MAX, 8420, UINT16_MAX, 8420, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16955, 573, UINT16_MAX, 573, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16958, UINT16_MAX, 8421, UINT16_MAX, 8421, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16960, 578, UINT16_MAX, 578, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16963, UINT16_MAX, 8422, UINT16_MAX, 8422, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1496, UINT16_MAX, 1496, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16965, 583, UINT16_MAX, 583, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16968, UINT16_MAX, 8423, UINT16_MAX, 8423, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16970, 588, UINT16_MAX, 588, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16973, UINT16_MAX, 8424, UINT16_MAX, 8424, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16975, 593, UINT16_MAX, 593, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16978, UINT16_MAX, 8425, UINT16_MAX, 8425, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 596, UINT16_MAX, 596, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8426, UINT16_MAX, 8426, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16981, 599, UINT16_MAX, 599, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16984, UINT16_MAX, 8427, UINT16_MAX, 8427, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16986, 604, UINT16_MAX, 604, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16989, UINT16_MAX, 8428, UINT16_MAX, 8428, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16991, 609, UINT16_MAX, 609, UINT16_MAX, 1567, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16994, UINT16_MAX, 8429, UINT16_MAX, 8429, 1570, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 16996, 614, UINT16_MAX, 614, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 16999, UINT16_MAX, 8430, UINT16_MAX, 8430, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17001, 619, UINT16_MAX, 619, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17004, UINT16_MAX, 8431, UINT16_MAX, 8431, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17006, 17006, 8432, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 17008, 626, UINT16_MAX, 626, 8433, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 17011, 626, 8434, 626, 8433, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 17013, UINT16_MAX, 8434, UINT16_MAX, 8433, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17015, 633, UINT16_MAX, 633, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17018, UINT16_MAX, 8435, UINT16_MAX, 8435, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 636, UINT16_MAX, 636, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 637, UINT16_MAX, 637, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17022, 640, UINT16_MAX, 640, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17025, UINT16_MAX, 8436, UINT16_MAX, 8436, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17027, 645, UINT16_MAX, 645, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17030, UINT16_MAX, 8437, UINT16_MAX, 8437, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17032, 650, UINT16_MAX, 650, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17035, UINT16_MAX, 8438, UINT16_MAX, 8438, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17037, 655, UINT16_MAX, 655, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17040, UINT16_MAX, 8439, UINT16_MAX, 8439, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17042, 660, UINT16_MAX, 660, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17045, UINT16_MAX, 8440, UINT16_MAX, 8440, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17047, 665, UINT16_MAX, 665, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17050, UINT16_MAX, 8441, UINT16_MAX, 8441, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17052, 670, UINT16_MAX, 670, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17055, UINT16_MAX, 8442, UINT16_MAX, 8442, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17057, 675, UINT16_MAX, 675, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17060, UINT16_MAX, 8443, UINT16_MAX, 8443, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17062, 680, UINT16_MAX, 680, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17065, UINT16_MAX, 8444, UINT16_MAX, 8444, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17067, 685, UINT16_MAX, 685, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17070, UINT16_MAX, 8445, UINT16_MAX, 8445, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17072, 690, UINT16_MAX, 690, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17075, UINT16_MAX, 8446, UINT16_MAX, 8446, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17077, 695, UINT16_MAX, 695, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17080, UINT16_MAX, 8447, UINT16_MAX, 8447, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17082, 700, UINT16_MAX, 700, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17085, UINT16_MAX, 8448, UINT16_MAX, 8448, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17087, 705, UINT16_MAX, 705, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17090, UINT16_MAX, 8449, UINT16_MAX, 8449, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17092, 710, UINT16_MAX, 710, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17095, UINT16_MAX, 8450, UINT16_MAX, 8450, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17097, 715, UINT16_MAX, 715, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17100, UINT16_MAX, 8451, UINT16_MAX, 8451, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17102, 720, UINT16_MAX, 720, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17105, UINT16_MAX, 8452, UINT16_MAX, 8452, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17107, 725, UINT16_MAX, 725, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17110, UINT16_MAX, 8453, UINT16_MAX, 8453, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 728, UINT16_MAX, 728, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8454, UINT16_MAX, 8454, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17113, 731, UINT16_MAX, 731, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17116, UINT16_MAX, 8455, UINT16_MAX, 8455, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 734, UINT16_MAX, 734, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8456, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 735, UINT16_MAX, 735, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1506, UINT16_MAX, 1506, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 736, UINT16_MAX, 736, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8457, UINT16_MAX, 8457, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17121, 739, UINT16_MAX, 739, UINT16_MAX, 1543, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17124, UINT16_MAX, 8458, UINT16_MAX, 8458, 1546, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17126, 744, UINT16_MAX, 744, UINT16_MAX, 2866, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17129, UINT16_MAX, 8459, UINT16_MAX, 8459, 2869, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17131, 749, UINT16_MAX, 749, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17134, UINT16_MAX, 8460, UINT16_MAX, 8460, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17136, 754, UINT16_MAX, 754, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17139, UINT16_MAX, 8461, UINT16_MAX, 8461, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17141, 759, UINT16_MAX, 759, UINT16_MAX, 1615, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17144, UINT16_MAX, 8462, UINT16_MAX, 8462, 1618, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17146, 764, UINT16_MAX, 764, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17149, UINT16_MAX, 8463, UINT16_MAX, 8463, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17151, 769, UINT16_MAX, 769, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17154, UINT16_MAX, 8464, UINT16_MAX, 8464, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8465, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8466, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8467, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7430, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8468, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8469, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 772, UINT16_MAX, 772, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 773, UINT16_MAX, 773, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8470, UINT16_MAX, 8470, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 774, UINT16_MAX, 774, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 775, UINT16_MAX, 775, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8471, UINT16_MAX, 8471, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8472, UINT16_MAX, 8472, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 776, UINT16_MAX, 776, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8473, UINT16_MAX, 8473, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 777, UINT16_MAX, 777, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 778, UINT16_MAX, 778, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 779, UINT16_MAX, 779, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 780, UINT16_MAX, 780, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8474, UINT16_MAX, 8474, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 781, UINT16_MAX, 781, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8475, UINT16_MAX, 8475, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 782, UINT16_MAX, 782, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8476, UINT16_MAX, 8476, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 783, UINT16_MAX, 783, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8477, UINT16_MAX, 8477, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 784, UINT16_MAX, 784, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8478, UINT16_MAX, 8478, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8479, UINT16_MAX, 8479, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8480, UINT16_MAX, 8480, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8481, UINT16_MAX, 8481, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8482, UINT16_MAX, 8482, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8483, UINT16_MAX, 8483, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1521, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8484, UINT16_MAX, 8484, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8485, UINT16_MAX, 8485, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7053, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8486, UINT16_MAX, 8486, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8487, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2822, UINT16_MAX, 2822, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8488, UINT16_MAX, 8488, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8489, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7054, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1522, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8490, UINT16_MAX, 8490, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8491, UINT16_MAX, 8491, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7057, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8492, UINT16_MAX, 8492, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7056, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8493, UINT16_MAX, 8493, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8494, UINT16_MAX, 8494, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7060, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8495, UINT16_MAX, 8495, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8496, UINT16_MAX, 8496, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8497, UINT16_MAX, 8497, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8498, UINT16_MAX, 8498, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8499, UINT16_MAX, 8499, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1528, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7067, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8500, UINT16_MAX, 8500, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1532, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8501, UINT16_MAX, 8501, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8502, UINT16_MAX, 8502, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1533, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1534, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8503, UINT16_MAX, 8503, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7073, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7074, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1535, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 786, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7075, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 787, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8504, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8505, UINT16_MAX, 8505, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7078, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8506, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8507, UINT16_MAX, 8507, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 788, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8508, UINT16_MAX, 8508, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8509, UINT16_MAX, 8509, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7061, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8510, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8511, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8512, UINT16_MAX, 8512, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8513, UINT16_MAX, 8513, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8514, UINT16_MAX, 8514, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8515, UINT16_MAX, 8515, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8516, UINT16_MAX, 8516, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8517, UINT16_MAX, 8517, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 5254, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7070, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7084, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1539, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1540, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8518, UINT16_MAX, 8518, 1576, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8519, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 801, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8520, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8521, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7087, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7047, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8522, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7058, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7059, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8523, UINT16_MAX, 8523, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8524, UINT16_MAX, 8524, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1530, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8525, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7085, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7086, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7048, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7051, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7050, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7080, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7082, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7079, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7055, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7062, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7063, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8526, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8527, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8528, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8529, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7, UINT16_MAX, 8530, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 785, UINT16_MAX, 8531, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 9, UINT16_MAX, 8532, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 17, UINT16_MAX, 8533, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 786, UINT16_MAX, 8534, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 787, UINT16_MAX, 8535, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 788, UINT16_MAX, 8536, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 22, UINT16_MAX, 8537, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 24, UINT16_MAX, 8538, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8539, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8540, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 17173, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 17175, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 17177, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 17179, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 17181, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 17183, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 489, UINT16_MAX, 8541, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 11, UINT16_MAX, 8542, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 18, UINT16_MAX, 8543, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 23, UINT16_MAX, 8544, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 801, UINT16_MAX, 8545, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32768, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32769, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32770, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32771, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32775, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32776, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32778, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32772, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32814, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32773, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32780, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32779, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32782, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32783, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32815, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32816, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 232, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 216, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32781, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32808, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32813, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32807, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32784, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32774, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32777, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32810, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32812, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32811, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32809, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 1, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 1, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32819, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, 802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, 803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32817, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, 804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, 17189, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 240, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, 807, 7437, UINT16_MAX, 7437, 32818, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 233, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 234, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 808, UINT16_MAX, 808, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8546, UINT16_MAX, 8546, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 809, UINT16_MAX, 809, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8547, UINT16_MAX, 8547, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 810, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 811, UINT16_MAX, 811, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8548, UINT16_MAX, 8548, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 17196, UINT16_MAX, 8549, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8550, UINT16_MAX, 8550, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8551, UINT16_MAX, 8551, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8552, UINT16_MAX, 8552, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, 814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 815, UINT16_MAX, 815, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 17200, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17202, 820, UINT16_MAX, 820, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, 821, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17206, 824, UINT16_MAX, 824, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17209, 827, UINT16_MAX, 827, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17212, 830, UINT16_MAX, 830, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17215, 833, UINT16_MAX, 833, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17218, 836, UINT16_MAX, 836, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17221, 839, UINT16_MAX, 839, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17224, 33610, 2659, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 845, UINT16_MAX, 845, UINT16_MAX, 1673, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 846, UINT16_MAX, 846, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 847, UINT16_MAX, 847, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 848, UINT16_MAX, 848, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 849, UINT16_MAX, 849, UINT16_MAX, 1726, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 850, UINT16_MAX, 850, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 851, UINT16_MAX, 851, UINT16_MAX, 1777, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 852, UINT16_MAX, 852, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 807, UINT16_MAX, 807, UINT16_MAX, 1830, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 853, UINT16_MAX, 853, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 854, UINT16_MAX, 854, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 35, UINT16_MAX, 35, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 855, UINT16_MAX, 855, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 856, UINT16_MAX, 856, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 857, UINT16_MAX, 857, UINT16_MAX, 1881, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 858, UINT16_MAX, 858, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 859, UINT16_MAX, 859, UINT16_MAX, 5027, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 860, UINT16_MAX, 860, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 861, UINT16_MAX, 861, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 862, UINT16_MAX, 862, UINT16_MAX, 1932, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 863, UINT16_MAX, 863, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 864, UINT16_MAX, 864, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 865, UINT16_MAX, 865, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 866, UINT16_MAX, 866, UINT16_MAX, 1983, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17251, 869, UINT16_MAX, 869, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17254, 872, UINT16_MAX, 872, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17257, UINT16_MAX, 2603, UINT16_MAX, 2603, 4904, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17259, UINT16_MAX, 2635, UINT16_MAX, 2635, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17261, UINT16_MAX, 2640, UINT16_MAX, 2640, 4913, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17263, UINT16_MAX, 2676, UINT16_MAX, 2676, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17265, 33651, 2693, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7431, UINT16_MAX, 7431, 2088, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7432, UINT16_MAX, 7432, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2847, UINT16_MAX, 2847, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7433, UINT16_MAX, 7433, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7434, UINT16_MAX, 7434, 2141, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7435, UINT16_MAX, 7435, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7436, UINT16_MAX, 7436, 2192, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 915, UINT16_MAX, 915, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7437, UINT16_MAX, 7437, 2245, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7438, UINT16_MAX, 7438, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7439, UINT16_MAX, 7439, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7440, UINT16_MAX, 7440, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7441, UINT16_MAX, 7441, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7442, UINT16_MAX, 7442, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7443, UINT16_MAX, 7443, 2401, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2848, UINT16_MAX, 2848, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7444, UINT16_MAX, 7444, 5023, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 860, 917, UINT16_MAX, 917, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 917, UINT16_MAX, 917, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7446, UINT16_MAX, 7446, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 897, UINT16_MAX, 897, 2349, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7447, UINT16_MAX, 7447, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7448, UINT16_MAX, 7448, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7449, UINT16_MAX, 7449, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 2836, UINT16_MAX, 2836, 2452, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17270, UINT16_MAX, 8553, UINT16_MAX, 8553, 2036, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17272, UINT16_MAX, 8554, UINT16_MAX, 8554, 2297, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17274, UINT16_MAX, 2745, UINT16_MAX, 2745, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17276, UINT16_MAX, 2714, UINT16_MAX, 2714, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17278, UINT16_MAX, 2750, UINT16_MAX, 2750, 5033, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 896, UINT16_MAX, 896, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 846, 846, 7432, UINT16_MAX, 7432, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 852, 852, 915, UINT16_MAX, 915, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 897, UINT16_MAX, UINT16_MAX, 8555, UINT16_MAX, 2505, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17282, UINT16_MAX, UINT16_MAX, 8556, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17284, UINT16_MAX, UINT16_MAX, 8557, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 863, 863, 7447, UINT16_MAX, 7447, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 858, 858, 2848, UINT16_MAX, 2848, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8558, UINT16_MAX, 8558, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 902, UINT16_MAX, 902, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8559, UINT16_MAX, 8559, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 903, UINT16_MAX, 903, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8560, UINT16_MAX, 8560, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 904, UINT16_MAX, 904, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7458, UINT16_MAX, 7458, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 905, UINT16_MAX, 905, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8561, UINT16_MAX, 8561, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 906, UINT16_MAX, 906, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8562, UINT16_MAX, 8562, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 907, UINT16_MAX, 907, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8563, UINT16_MAX, 8563, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 908, UINT16_MAX, 908, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8564, UINT16_MAX, 8564, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 909, UINT16_MAX, 909, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8565, UINT16_MAX, 8565, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 910, UINT16_MAX, 910, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8566, UINT16_MAX, 8566, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 911, UINT16_MAX, 911, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8567, UINT16_MAX, 8567, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 912, UINT16_MAX, 912, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8568, UINT16_MAX, 8568, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 913, UINT16_MAX, 913, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8569, UINT16_MAX, 8569, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 853, 853, 7438, UINT16_MAX, 7438, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 859, 859, 7444, UINT16_MAX, 7444, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 914, UINT16_MAX, 8570, UINT16_MAX, 8570, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8571, UINT16_MAX, 8571, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 915, 852, UINT16_MAX, 852, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 849, 849, 7434, UINT16_MAX, 7434, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 916, UINT16_MAX, 916, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8572, UINT16_MAX, 8572, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 917, 918, UINT16_MAX, 918, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 919, UINT16_MAX, 919, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8573, UINT16_MAX, 8573, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8574, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 920, UINT16_MAX, 920, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 921, UINT16_MAX, 921, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 922, UINT16_MAX, 922, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17307, 925, UINT16_MAX, 925, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17310, 928, UINT16_MAX, 928, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 929, UINT16_MAX, 929, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17314, 932, UINT16_MAX, 932, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 933, UINT16_MAX, 933, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 934, UINT16_MAX, 934, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 935, UINT16_MAX, 935, UINT16_MAX, 2525, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17320, 938, UINT16_MAX, 938, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 939, UINT16_MAX, 939, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 940, UINT16_MAX, 940, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 941, UINT16_MAX, 941, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 942, UINT16_MAX, 942, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17327, 945, UINT16_MAX, 945, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17330, 948, UINT16_MAX, 948, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17333, 951, UINT16_MAX, 951, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 952, UINT16_MAX, 952, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 953, UINT16_MAX, 953, UINT16_MAX, 2615, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 954, UINT16_MAX, 954, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 955, UINT16_MAX, 955, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 956, UINT16_MAX, 956, UINT16_MAX, 2522, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 957, UINT16_MAX, 957, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 958, UINT16_MAX, 958, UINT16_MAX, 2511, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 959, UINT16_MAX, 959, UINT16_MAX, 2601, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 960, UINT16_MAX, 960, UINT16_MAX, 2635, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 961, UINT16_MAX, 961, UINT16_MAX, 2531, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17346, 964, UINT16_MAX, 964, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 965, UINT16_MAX, 965, UINT16_MAX, 2528, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 966, UINT16_MAX, 966, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 967, UINT16_MAX, 967, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 968, UINT16_MAX, 968, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 969, UINT16_MAX, 969, UINT16_MAX, 2641, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 970, UINT16_MAX, 970, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 971, UINT16_MAX, 971, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 972, UINT16_MAX, 972, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 973, UINT16_MAX, 973, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 974, UINT16_MAX, 974, UINT16_MAX, 2542, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 975, UINT16_MAX, 975, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 976, UINT16_MAX, 976, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 977, UINT16_MAX, 977, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 978, UINT16_MAX, 978, UINT16_MAX, 2659, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 979, UINT16_MAX, 979, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 980, UINT16_MAX, 980, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 981, UINT16_MAX, 981, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 982, UINT16_MAX, 982, UINT16_MAX, 2665, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 983, UINT16_MAX, 983, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 984, UINT16_MAX, 984, UINT16_MAX, 2653, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 985, UINT16_MAX, 985, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 986, UINT16_MAX, 986, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8575, UINT16_MAX, 8575, 2622, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8576, UINT16_MAX, 8576, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8577, UINT16_MAX, 8577, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8578, UINT16_MAX, 8578, 2575, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8579, UINT16_MAX, 8579, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8580, UINT16_MAX, 8580, 2564, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8581, UINT16_MAX, 8581, 2608, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8582, UINT16_MAX, 8582, 2638, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8583, UINT16_MAX, 8583, 2553, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17371, UINT16_MAX, 8584, UINT16_MAX, 8584, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8585, UINT16_MAX, 8585, 2581, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8586, UINT16_MAX, 8586, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8587, UINT16_MAX, 8587, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8588, UINT16_MAX, 8588, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8589, UINT16_MAX, 8589, 2644, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8590, UINT16_MAX, 8590, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8591, UINT16_MAX, 8591, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8592, UINT16_MAX, 8592, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8593, UINT16_MAX, 8593, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8594, UINT16_MAX, 8594, 2584, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8595, UINT16_MAX, 8595, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8596, UINT16_MAX, 8596, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8597, UINT16_MAX, 8597, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8598, UINT16_MAX, 8598, 2662, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8599, UINT16_MAX, 8599, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8600, UINT16_MAX, 8600, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8601, UINT16_MAX, 8601, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8602, UINT16_MAX, 8602, 2668, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8603, UINT16_MAX, 8603, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8604, UINT16_MAX, 8604, 2656, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8605, UINT16_MAX, 8605, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8606, UINT16_MAX, 8606, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17373, UINT16_MAX, 8607, UINT16_MAX, 8607, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17375, UINT16_MAX, 8608, UINT16_MAX, 8608, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8609, UINT16_MAX, 8609, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17377, UINT16_MAX, 8610, UINT16_MAX, 8610, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8611, UINT16_MAX, 8611, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8612, UINT16_MAX, 8612, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8613, UINT16_MAX, 8613, 2578, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17379, UINT16_MAX, 8614, UINT16_MAX, 8614, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8615, UINT16_MAX, 8615, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8616, UINT16_MAX, 8616, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8617, UINT16_MAX, 8617, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8618, UINT16_MAX, 8618, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17381, UINT16_MAX, 8619, UINT16_MAX, 8619, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17383, UINT16_MAX, 8620, UINT16_MAX, 8620, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17385, UINT16_MAX, 8621, UINT16_MAX, 8621, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8622, UINT16_MAX, 8622, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1003, UINT16_MAX, 1003, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8623, UINT16_MAX, 8623, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1004, UINT16_MAX, 1004, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8624, UINT16_MAX, 8624, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1005, UINT16_MAX, 1005, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8625, UINT16_MAX, 8625, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1006, UINT16_MAX, 1006, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8626, UINT16_MAX, 8626, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1007, UINT16_MAX, 1007, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8627, UINT16_MAX, 8627, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1008, UINT16_MAX, 1008, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8628, UINT16_MAX, 8628, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1009, UINT16_MAX, 1009, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8629, UINT16_MAX, 8629, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1010, UINT16_MAX, 1010, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8630, UINT16_MAX, 8630, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1011, UINT16_MAX, 1011, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8631, UINT16_MAX, 8631, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1012, UINT16_MAX, 1012, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8632, UINT16_MAX, 8632, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1013, UINT16_MAX, 1013, UINT16_MAX, 2595, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8633, UINT16_MAX, 8633, 2598, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17398, 1016, UINT16_MAX, 1016, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17401, UINT16_MAX, 8634, UINT16_MAX, 8634, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1019, UINT16_MAX, 1019, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8635, UINT16_MAX, 8635, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1020, UINT16_MAX, 1020, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8636, UINT16_MAX, 8636, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1021, UINT16_MAX, 1021, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8637, UINT16_MAX, 8637, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1022, UINT16_MAX, 1022, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8638, UINT16_MAX, 8638, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1023, UINT16_MAX, 1023, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8639, UINT16_MAX, 8639, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ME, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1024, UINT16_MAX, 1024, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8640, UINT16_MAX, 8640, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1025, UINT16_MAX, 1025, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8641, UINT16_MAX, 8641, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1026, UINT16_MAX, 1026, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8642, UINT16_MAX, 8642, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1027, UINT16_MAX, 1027, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8643, UINT16_MAX, 8643, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1028, UINT16_MAX, 1028, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8644, UINT16_MAX, 8644, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1029, UINT16_MAX, 1029, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8645, UINT16_MAX, 8645, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1030, UINT16_MAX, 1030, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8646, UINT16_MAX, 8646, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1031, UINT16_MAX, 1031, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8647, UINT16_MAX, 8647, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1032, UINT16_MAX, 1032, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8648, UINT16_MAX, 8648, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1033, UINT16_MAX, 1033, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8649, UINT16_MAX, 8649, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1034, UINT16_MAX, 1034, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8650, UINT16_MAX, 8650, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1035, UINT16_MAX, 1035, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8651, UINT16_MAX, 8651, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1036, UINT16_MAX, 1036, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8652, UINT16_MAX, 8652, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1037, UINT16_MAX, 1037, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8653, UINT16_MAX, 8653, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1038, UINT16_MAX, 1038, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8654, UINT16_MAX, 8654, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1039, UINT16_MAX, 1039, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8655, UINT16_MAX, 8655, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1040, UINT16_MAX, 1040, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8656, UINT16_MAX, 8656, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1041, UINT16_MAX, 1041, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8657, UINT16_MAX, 8657, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1042, UINT16_MAX, 1042, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8658, UINT16_MAX, 8658, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1043, UINT16_MAX, 1043, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8659, UINT16_MAX, 8659, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1044, UINT16_MAX, 1044, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8660, UINT16_MAX, 8660, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1045, UINT16_MAX, 1045, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8661, UINT16_MAX, 8661, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1046, UINT16_MAX, 1046, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8662, UINT16_MAX, 8662, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1047, UINT16_MAX, 1047, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8663, UINT16_MAX, 8663, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1048, UINT16_MAX, 1048, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8664, UINT16_MAX, 8664, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1049, UINT16_MAX, 1049, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8665, UINT16_MAX, 8665, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1050, UINT16_MAX, 1050, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8666, UINT16_MAX, 8666, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1051, UINT16_MAX, 1051, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17436, 1054, UINT16_MAX, 1054, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17439, UINT16_MAX, 8667, UINT16_MAX, 8667, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1057, UINT16_MAX, 1057, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8668, UINT16_MAX, 8668, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1058, UINT16_MAX, 1058, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8669, UINT16_MAX, 8669, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1059, UINT16_MAX, 1059, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8670, UINT16_MAX, 8670, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1060, UINT16_MAX, 1060, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8671, UINT16_MAX, 8671, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1061, UINT16_MAX, 1061, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8672, UINT16_MAX, 8672, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1062, UINT16_MAX, 1062, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8673, UINT16_MAX, 8673, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8674, UINT16_MAX, 8674, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17447, 1065, UINT16_MAX, 1065, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17450, UINT16_MAX, 8675, UINT16_MAX, 8675, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17452, 1070, UINT16_MAX, 1070, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17455, UINT16_MAX, 8676, UINT16_MAX, 8676, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1073, UINT16_MAX, 1073, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8677, UINT16_MAX, 8677, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17458, 1076, UINT16_MAX, 1076, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17461, UINT16_MAX, 8678, UINT16_MAX, 8678, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1079, UINT16_MAX, 1079, UINT16_MAX, 2629, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8679, UINT16_MAX, 8679, 2632, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17464, 1082, UINT16_MAX, 1082, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17467, UINT16_MAX, 8680, UINT16_MAX, 8680, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17469, 1087, UINT16_MAX, 1087, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17472, UINT16_MAX, 8681, UINT16_MAX, 8681, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17474, 1092, UINT16_MAX, 1092, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17477, UINT16_MAX, 8682, UINT16_MAX, 8682, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1095, UINT16_MAX, 1095, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8683, UINT16_MAX, 8683, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17480, 1098, UINT16_MAX, 1098, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17483, UINT16_MAX, 8684, UINT16_MAX, 8684, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17485, 1103, UINT16_MAX, 1103, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17488, UINT16_MAX, 8685, UINT16_MAX, 8685, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17490, 1108, UINT16_MAX, 1108, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17493, UINT16_MAX, 8686, UINT16_MAX, 8686, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1111, UINT16_MAX, 1111, UINT16_MAX, 2647, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8687, UINT16_MAX, 8687, 2650, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17496, 1114, UINT16_MAX, 1114, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17499, UINT16_MAX, 8688, UINT16_MAX, 8688, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17501, 1119, UINT16_MAX, 1119, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17504, UINT16_MAX, 8689, UINT16_MAX, 8689, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17506, 1124, UINT16_MAX, 1124, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17509, UINT16_MAX, 8690, UINT16_MAX, 8690, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17511, 1129, UINT16_MAX, 1129, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17514, UINT16_MAX, 8691, UINT16_MAX, 8691, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17516, 1134, UINT16_MAX, 1134, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17519, UINT16_MAX, 8692, UINT16_MAX, 8692, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17521, 1139, UINT16_MAX, 1139, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17524, UINT16_MAX, 8693, UINT16_MAX, 8693, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1142, UINT16_MAX, 1142, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8694, UINT16_MAX, 8694, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17527, 1145, UINT16_MAX, 1145, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17530, UINT16_MAX, 8695, UINT16_MAX, 8695, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1148, UINT16_MAX, 1148, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8696, UINT16_MAX, 8696, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1149, UINT16_MAX, 1149, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8697, UINT16_MAX, 8697, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1150, UINT16_MAX, 1150, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8698, UINT16_MAX, 8698, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1151, UINT16_MAX, 1151, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8699, UINT16_MAX, 8699, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1152, UINT16_MAX, 1152, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8700, UINT16_MAX, 8700, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1153, UINT16_MAX, 1153, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8701, UINT16_MAX, 8701, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1154, UINT16_MAX, 1154, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8702, UINT16_MAX, 8702, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1155, UINT16_MAX, 1155, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8703, UINT16_MAX, 8703, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1156, UINT16_MAX, 1156, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8704, UINT16_MAX, 8704, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1157, UINT16_MAX, 1157, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8705, UINT16_MAX, 8705, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1158, UINT16_MAX, 1158, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8706, UINT16_MAX, 8706, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1159, UINT16_MAX, 1159, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8707, UINT16_MAX, 8707, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1160, UINT16_MAX, 1160, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8708, UINT16_MAX, 8708, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1161, UINT16_MAX, 1161, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8709, UINT16_MAX, 8709, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1162, UINT16_MAX, 1162, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8710, UINT16_MAX, 8710, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1163, UINT16_MAX, 1163, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8711, UINT16_MAX, 8711, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1164, UINT16_MAX, 1164, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8712, UINT16_MAX, 8712, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1165, UINT16_MAX, 1165, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8713, UINT16_MAX, 8713, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1166, UINT16_MAX, 1166, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8714, UINT16_MAX, 8714, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1167, UINT16_MAX, 1167, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8715, UINT16_MAX, 8715, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1168, UINT16_MAX, 1168, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8716, UINT16_MAX, 8716, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1169, UINT16_MAX, 1169, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8717, UINT16_MAX, 8717, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1170, UINT16_MAX, 1170, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8718, UINT16_MAX, 8718, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1171, UINT16_MAX, 1171, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8719, UINT16_MAX, 8719, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1172, UINT16_MAX, 1172, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8720, UINT16_MAX, 8720, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1173, UINT16_MAX, 1173, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8721, UINT16_MAX, 8721, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1174, UINT16_MAX, 1174, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8722, UINT16_MAX, 8722, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1175, UINT16_MAX, 1175, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1176, UINT16_MAX, 1176, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1177, UINT16_MAX, 1177, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1178, UINT16_MAX, 1178, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1179, UINT16_MAX, 1179, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1180, UINT16_MAX, 1180, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1181, UINT16_MAX, 1181, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1182, UINT16_MAX, 1182, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1183, UINT16_MAX, 1183, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1184, UINT16_MAX, 1184, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1185, UINT16_MAX, 1185, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1186, UINT16_MAX, 1186, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1187, UINT16_MAX, 1187, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1188, UINT16_MAX, 1188, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1189, UINT16_MAX, 1189, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1190, UINT16_MAX, 1190, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1191, UINT16_MAX, 1191, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1192, UINT16_MAX, 1192, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1193, UINT16_MAX, 1193, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1194, UINT16_MAX, 1194, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1195, UINT16_MAX, 1195, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1196, UINT16_MAX, 1196, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1197, UINT16_MAX, 1197, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1198, UINT16_MAX, 1198, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1199, UINT16_MAX, 1199, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1200, UINT16_MAX, 1200, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1201, UINT16_MAX, 1201, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1202, UINT16_MAX, 1202, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1203, UINT16_MAX, 1203, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1204, UINT16_MAX, 1204, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1205, UINT16_MAX, 1205, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1206, UINT16_MAX, 1206, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1207, UINT16_MAX, 1207, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1208, UINT16_MAX, 1208, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1209, UINT16_MAX, 1209, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1210, UINT16_MAX, 1210, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1211, UINT16_MAX, 1211, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1212, UINT16_MAX, 1212, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8723, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8724, UINT16_MAX, 8724, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8725, UINT16_MAX, 8725, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8726, UINT16_MAX, 8726, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8727, UINT16_MAX, 8727, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8728, UINT16_MAX, 8728, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8729, UINT16_MAX, 8729, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8730, UINT16_MAX, 8730, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8731, UINT16_MAX, 8731, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8732, UINT16_MAX, 8732, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8733, UINT16_MAX, 8733, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8734, UINT16_MAX, 8734, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8735, UINT16_MAX, 8735, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8736, UINT16_MAX, 8736, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8737, UINT16_MAX, 8737, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8738, UINT16_MAX, 8738, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8739, UINT16_MAX, 8739, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8740, UINT16_MAX, 8740, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8741, UINT16_MAX, 8741, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8742, UINT16_MAX, 8742, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8743, UINT16_MAX, 8743, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8744, UINT16_MAX, 8744, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8745, UINT16_MAX, 8745, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8746, UINT16_MAX, 8746, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8747, UINT16_MAX, 8747, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8748, UINT16_MAX, 8748, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8749, UINT16_MAX, 8749, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8750, UINT16_MAX, 8750, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8751, UINT16_MAX, 8751, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8752, UINT16_MAX, 8752, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8753, UINT16_MAX, 8753, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8754, UINT16_MAX, 8754, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8755, UINT16_MAX, 8755, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8756, UINT16_MAX, 8756, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8757, UINT16_MAX, 8757, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8758, UINT16_MAX, 8758, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8759, UINT16_MAX, 8759, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8760, UINT16_MAX, 8760, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8761, UINT16_MAX, 8761, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 17597, 17597, 8762, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8763, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 222, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 228, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 10, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 11, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 12, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 13, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 14, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 15, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 16, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 17, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 18, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 19, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 20, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 21, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 22, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 23, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 24, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 25, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_AN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_PREPEND}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 30, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 31, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 32, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 17599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 17601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 17603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 17605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 17607, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2671, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2676, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2679, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 27, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 28, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 29, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 33, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 34, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32785, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32786, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32787, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_AN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_AN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 35, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, 17609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, 17611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, 17613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, 17615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 17617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2685, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 17619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2688, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, 17621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2682, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_PREPEND}, + {UTF8PROC_CATEGORY_MN, 36, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2691, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2694, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2697, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17627, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 7, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32788, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 9, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17631, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17633, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17637, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17639, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17641, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17643, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 7, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32789, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2700, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17645, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17647, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32790, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17649, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17651, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17653, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17655, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17657, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17661, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17663, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17665, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32792, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2704, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17667, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17669, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17671, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32791, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32793, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2709, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17677, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32795, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2712, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2716, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17681, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17683, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32794, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2719, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 84, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 91, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32796, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2722, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32799, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2725, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2730, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32797, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32798, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32800, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2733, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2737, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17697, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17699, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17701, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_PREPEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32801, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 9, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32802, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32803, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2740, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17703, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17705, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2745, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17707, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17709, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32804, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 17711, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MN, 103, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 107, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 17713, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MN, 118, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 122, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 17715, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 17717, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NOBREAK, 1335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 216, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17720, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17724, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17726, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17728, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17730, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 129, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 130, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17732, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 132, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17734, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17736, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, UTF8PROC_DECOMP_TYPE_COMPAT, 17738, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17740, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, UTF8PROC_DECOMP_TYPE_COMPAT, 17742, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17744, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17746, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17748, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17750, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17752, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17754, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 17756, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2748, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17758, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32805, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1376, UINT16_MAX, 1376, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1377, UINT16_MAX, 1377, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1378, UINT16_MAX, 1378, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1379, UINT16_MAX, 1379, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1380, UINT16_MAX, 1380, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1381, UINT16_MAX, 1381, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1382, UINT16_MAX, 1382, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1383, UINT16_MAX, 1383, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1384, UINT16_MAX, 1384, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1385, UINT16_MAX, 1385, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1386, UINT16_MAX, 1386, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1387, UINT16_MAX, 1387, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1388, UINT16_MAX, 1388, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1389, UINT16_MAX, 1389, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1390, UINT16_MAX, 1390, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1391, UINT16_MAX, 1391, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1392, UINT16_MAX, 1392, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1393, UINT16_MAX, 1393, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1394, UINT16_MAX, 1394, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1395, UINT16_MAX, 1395, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1396, UINT16_MAX, 1396, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1397, UINT16_MAX, 1397, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1398, UINT16_MAX, 1398, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1399, UINT16_MAX, 1399, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1400, UINT16_MAX, 1400, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1401, UINT16_MAX, 1401, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1402, UINT16_MAX, 1402, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1403, UINT16_MAX, 1403, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1404, UINT16_MAX, 1404, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1405, UINT16_MAX, 1405, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1406, UINT16_MAX, 1406, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1407, UINT16_MAX, 1407, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1408, UINT16_MAX, 1408, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1409, UINT16_MAX, 1409, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1410, UINT16_MAX, 1410, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1411, UINT16_MAX, 1411, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1412, UINT16_MAX, 1412, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1413, UINT16_MAX, 1413, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1414, UINT16_MAX, 1414, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1415, UINT16_MAX, 1415, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8764, UINT16_MAX, 1446, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8765, UINT16_MAX, 1447, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8766, UINT16_MAX, 1448, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8767, UINT16_MAX, 1449, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8768, UINT16_MAX, 1450, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8769, UINT16_MAX, 1451, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8770, UINT16_MAX, 1452, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8771, UINT16_MAX, 1453, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8772, UINT16_MAX, 1454, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8773, UINT16_MAX, 1455, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8774, UINT16_MAX, 1456, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8775, UINT16_MAX, 1457, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8776, UINT16_MAX, 1416, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8777, UINT16_MAX, 1458, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8778, UINT16_MAX, 1459, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8779, UINT16_MAX, 1460, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8780, UINT16_MAX, 1461, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8781, UINT16_MAX, 1462, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8782, UINT16_MAX, 1463, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8783, UINT16_MAX, 1464, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8784, UINT16_MAX, 1465, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8785, UINT16_MAX, 1466, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8786, UINT16_MAX, 1467, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8787, UINT16_MAX, 1468, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8788, UINT16_MAX, 1469, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8789, UINT16_MAX, 1470, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8790, UINT16_MAX, 1471, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8791, UINT16_MAX, 1472, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8792, UINT16_MAX, 1473, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8793, UINT16_MAX, 1474, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8794, UINT16_MAX, 1475, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8795, UINT16_MAX, 1476, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8796, UINT16_MAX, 1477, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8797, UINT16_MAX, 1478, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8798, UINT16_MAX, 1479, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8799, UINT16_MAX, 1480, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8800, UINT16_MAX, 1481, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8801, UINT16_MAX, 1482, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8802, UINT16_MAX, 1483, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8803, UINT16_MAX, 1484, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8804, UINT16_MAX, 1485, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8805, UINT16_MAX, 1486, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8806, UINT16_MAX, 1487, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1416, UINT16_MAX, 8807, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8808, UINT16_MAX, 1488, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8809, UINT16_MAX, 1489, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8810, UINT16_MAX, 1490, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_L}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, false, 2, 0, UTF8PROC_BOUNDCLASS_L}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, false, 1, 0, UTF8PROC_BOUNDCLASS_V}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_V}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_T}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8811, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8812, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8813, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8814, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8815, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8816, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8817, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8818, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8819, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8820, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8821, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8822, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8823, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8824, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8825, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8826, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8827, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8828, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8829, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8830, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8831, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8832, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8833, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8834, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8835, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8836, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8837, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8838, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8839, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8840, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8841, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8842, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8843, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8844, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8845, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8846, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8847, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8848, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8849, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8850, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8851, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8852, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8853, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8854, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8855, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8856, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8857, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8858, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8859, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8860, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8861, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8862, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8863, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8864, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8865, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8866, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8867, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8868, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8869, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8870, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8871, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8872, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8873, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8874, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8875, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8876, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8877, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8878, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8879, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8880, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8881, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8882, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8883, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8884, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8885, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8886, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8887, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8888, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8889, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8890, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8891, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8892, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8893, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8894, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8895, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 8896, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1417, 1417, UINT16_MAX, 1417, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1418, 1418, UINT16_MAX, 1418, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1419, 1419, UINT16_MAX, 1419, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1420, 1420, UINT16_MAX, 1420, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1421, 1421, UINT16_MAX, 1421, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1422, 1422, UINT16_MAX, 1422, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MC, 9, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2751, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2754, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17809, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2757, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17811, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2760, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17813, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2763, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17815, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2766, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 17817, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32806, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2769, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2772, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17821, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2775, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2778, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17823, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17825, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 2781, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 17827, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 955, 8577, UINT16_MAX, 8577, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 957, 8579, UINT16_MAX, 8579, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 969, 8589, UINT16_MAX, 8589, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 972, 8592, UINT16_MAX, 8592, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 973, 8593, UINT16_MAX, 8593, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 981, 8601, UINT16_MAX, 8601, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1004, 8624, UINT16_MAX, 8624, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1445, 8897, UINT16_MAX, 8897, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1446, UINT16_MAX, 1446, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1447, UINT16_MAX, 1447, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1448, UINT16_MAX, 1448, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1449, UINT16_MAX, 1449, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1450, UINT16_MAX, 1450, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1451, UINT16_MAX, 1451, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1452, UINT16_MAX, 1452, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1453, UINT16_MAX, 1453, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1454, UINT16_MAX, 1454, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1455, UINT16_MAX, 1455, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1456, UINT16_MAX, 1456, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1457, UINT16_MAX, 1457, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1416, UINT16_MAX, 1416, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1458, UINT16_MAX, 1458, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1459, UINT16_MAX, 1459, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1460, UINT16_MAX, 1460, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1461, UINT16_MAX, 1461, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1462, UINT16_MAX, 1462, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1463, UINT16_MAX, 1463, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1464, UINT16_MAX, 1464, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1465, UINT16_MAX, 1465, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1466, UINT16_MAX, 1466, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1467, UINT16_MAX, 1467, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1468, UINT16_MAX, 1468, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1469, UINT16_MAX, 1469, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1470, UINT16_MAX, 1470, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1471, UINT16_MAX, 1471, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1472, UINT16_MAX, 1472, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1473, UINT16_MAX, 1473, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1474, UINT16_MAX, 1474, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1475, UINT16_MAX, 1475, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1476, UINT16_MAX, 1476, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1477, UINT16_MAX, 1477, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1478, UINT16_MAX, 1478, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1479, UINT16_MAX, 1479, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1480, UINT16_MAX, 1480, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1481, UINT16_MAX, 1481, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1482, UINT16_MAX, 1482, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1483, UINT16_MAX, 1483, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1484, UINT16_MAX, 1484, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1485, UINT16_MAX, 1485, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1486, UINT16_MAX, 1486, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1487, UINT16_MAX, 1487, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1488, UINT16_MAX, 1488, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1489, UINT16_MAX, 1489, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1490, UINT16_MAX, 1490, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8898, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8899, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1514, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8900, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8901, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8902, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8903, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8904, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8905, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8906, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8907, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8908, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8909, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8910, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8911, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8912, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8913, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8914, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8915, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8916, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8917, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8918, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1516, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1517, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8919, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8920, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8921, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8922, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1538, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1518, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8923, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8924, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8925, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8926, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8927, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8928, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8929, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1519, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8930, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8931, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8932, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8933, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8934, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8935, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1491, UINT16_MAX, 8936, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1492, UINT16_MAX, 8937, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1493, UINT16_MAX, 8938, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8939, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1494, UINT16_MAX, 8940, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1495, UINT16_MAX, 8941, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1496, UINT16_MAX, 8942, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1497, UINT16_MAX, 8943, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1498, UINT16_MAX, 8944, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1499, UINT16_MAX, 8945, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1500, UINT16_MAX, 8946, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1501, UINT16_MAX, 8947, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1502, UINT16_MAX, 8948, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1503, UINT16_MAX, 8949, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1504, UINT16_MAX, 8950, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8951, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1505, UINT16_MAX, 8952, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1506, UINT16_MAX, 8953, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1507, UINT16_MAX, 8954, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1508, UINT16_MAX, 8955, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1509, UINT16_MAX, 8956, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1510, UINT16_MAX, 8957, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1511, UINT16_MAX, 8958, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 0, UINT16_MAX, 8959, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1512, UINT16_MAX, 8960, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1513, UINT16_MAX, 8961, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1514, UINT16_MAX, 8962, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1, UINT16_MAX, 8963, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3, UINT16_MAX, 8964, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 4, UINT16_MAX, 8965, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 485, UINT16_MAX, 8966, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 486, UINT16_MAX, 8967, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1515, UINT16_MAX, 8968, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 6, UINT16_MAX, 8969, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8970, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 10, UINT16_MAX, 8971, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 12, UINT16_MAX, 8972, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 355, UINT16_MAX, 8973, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 14, UINT16_MAX, 8974, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 479, UINT16_MAX, 8975, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1516, UINT16_MAX, 8976, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1517, UINT16_MAX, 8977, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 15, UINT16_MAX, 8978, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 19, UINT16_MAX, 8979, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 20, UINT16_MAX, 8980, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1518, UINT16_MAX, 8981, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 493, UINT16_MAX, 8982, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 21, UINT16_MAX, 8983, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1519, UINT16_MAX, 8984, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 846, UINT16_MAX, 8985, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 847, UINT16_MAX, 8986, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 848, UINT16_MAX, 8987, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 863, UINT16_MAX, 8988, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 864, UINT16_MAX, 8989, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 8, UINT16_MAX, 8990, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 17, UINT16_MAX, 8991, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 20, UINT16_MAX, 8992, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 21, UINT16_MAX, 8993, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 846, UINT16_MAX, 8994, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 847, UINT16_MAX, 8995, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 859, UINT16_MAX, 8996, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 863, UINT16_MAX, 8997, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 864, UINT16_MAX, 8998, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8999, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9000, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9001, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9002, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9003, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9004, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9005, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9006, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9007, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9008, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9009, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9010, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9011, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 968, UINT16_MAX, 9012, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9013, UINT16_MAX, 9013, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9014, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1526, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9015, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9016, UINT16_MAX, 9016, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9017, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9018, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9019, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9020, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9021, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9022, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9023, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 1529, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9024, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9025, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9026, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9027, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9028, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9029, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9030, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9031, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9032, UINT16_MAX, 9032, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9033, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9034, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7052, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9035, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9036, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9037, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9038, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9039, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9040, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9041, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9042, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9043, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1520, UINT16_MAX, 9044, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 2, UINT16_MAX, 9045, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1521, UINT16_MAX, 9046, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 94, UINT16_MAX, 9047, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1515, UINT16_MAX, 9048, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5, UINT16_MAX, 9049, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1522, UINT16_MAX, 9050, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1523, UINT16_MAX, 9051, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1524, UINT16_MAX, 9052, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 491, UINT16_MAX, 9053, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 490, UINT16_MAX, 9054, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1525, UINT16_MAX, 9055, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1526, UINT16_MAX, 9056, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1527, UINT16_MAX, 9057, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1528, UINT16_MAX, 9058, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1529, UINT16_MAX, 9059, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1530, UINT16_MAX, 9060, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1531, UINT16_MAX, 9061, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1532, UINT16_MAX, 9062, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 494, UINT16_MAX, 9063, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1533, UINT16_MAX, 9064, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1534, UINT16_MAX, 9065, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 495, UINT16_MAX, 9066, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1535, UINT16_MAX, 9067, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1536, UINT16_MAX, 9068, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 505, UINT16_MAX, 9069, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1537, UINT16_MAX, 9070, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 778, UINT16_MAX, 9071, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 513, UINT16_MAX, 9072, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1538, UINT16_MAX, 9073, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 514, UINT16_MAX, 9074, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 779, UINT16_MAX, 9075, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 25, UINT16_MAX, 9076, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1539, UINT16_MAX, 9077, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1540, UINT16_MAX, 9078, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 517, UINT16_MAX, 9079, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 852, UINT16_MAX, 9080, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 214, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 218, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17925, 1543, UINT16_MAX, 1543, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17928, UINT16_MAX, 9081, UINT16_MAX, 9081, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17930, 1548, UINT16_MAX, 1548, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17933, UINT16_MAX, 9082, UINT16_MAX, 9082, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17935, 1553, UINT16_MAX, 1553, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17938, UINT16_MAX, 9083, UINT16_MAX, 9083, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17940, 1558, UINT16_MAX, 1558, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17943, UINT16_MAX, 9084, UINT16_MAX, 9084, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17945, 1563, UINT16_MAX, 1563, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17948, UINT16_MAX, 9085, UINT16_MAX, 9085, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17950, 1568, UINT16_MAX, 1568, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17953, UINT16_MAX, 9086, UINT16_MAX, 9086, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17955, 1573, UINT16_MAX, 1573, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17958, UINT16_MAX, 9087, UINT16_MAX, 9087, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17960, 1578, UINT16_MAX, 1578, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17963, UINT16_MAX, 9088, UINT16_MAX, 9088, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17965, 1583, UINT16_MAX, 1583, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17968, UINT16_MAX, 9089, UINT16_MAX, 9089, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17970, 1588, UINT16_MAX, 1588, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17973, UINT16_MAX, 9090, UINT16_MAX, 9090, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17975, 1593, UINT16_MAX, 1593, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17978, UINT16_MAX, 9091, UINT16_MAX, 9091, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17980, 1598, UINT16_MAX, 1598, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17983, UINT16_MAX, 9092, UINT16_MAX, 9092, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17985, 1603, UINT16_MAX, 1603, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17988, UINT16_MAX, 9093, UINT16_MAX, 9093, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17990, 1608, UINT16_MAX, 1608, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17993, UINT16_MAX, 9094, UINT16_MAX, 9094, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 17995, 1613, UINT16_MAX, 1613, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 17998, UINT16_MAX, 9095, UINT16_MAX, 9095, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18000, 1618, UINT16_MAX, 1618, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18003, UINT16_MAX, 9096, UINT16_MAX, 9096, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18005, 1623, UINT16_MAX, 1623, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18008, UINT16_MAX, 9097, UINT16_MAX, 9097, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18010, 1628, UINT16_MAX, 1628, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18013, UINT16_MAX, 9098, UINT16_MAX, 9098, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18015, 1633, UINT16_MAX, 1633, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18018, UINT16_MAX, 9099, UINT16_MAX, 9099, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18020, 1638, UINT16_MAX, 1638, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18023, UINT16_MAX, 9100, UINT16_MAX, 9100, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18025, 1643, UINT16_MAX, 1643, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18028, UINT16_MAX, 9101, UINT16_MAX, 9101, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18030, 1648, UINT16_MAX, 1648, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18033, UINT16_MAX, 9102, UINT16_MAX, 9102, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18035, 1653, UINT16_MAX, 1653, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18038, UINT16_MAX, 9103, UINT16_MAX, 9103, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18040, 1658, UINT16_MAX, 1658, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18043, UINT16_MAX, 9104, UINT16_MAX, 9104, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18045, 1663, UINT16_MAX, 1663, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18048, UINT16_MAX, 9105, UINT16_MAX, 9105, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18050, 1668, UINT16_MAX, 1668, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18053, UINT16_MAX, 9106, UINT16_MAX, 9106, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18055, 1673, UINT16_MAX, 1673, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18058, UINT16_MAX, 9107, UINT16_MAX, 9107, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18060, 1678, UINT16_MAX, 1678, UINT16_MAX, 2884, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18063, UINT16_MAX, 9108, UINT16_MAX, 9108, 2887, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18065, 1683, UINT16_MAX, 1683, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18068, UINT16_MAX, 9109, UINT16_MAX, 9109, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18070, 1688, UINT16_MAX, 1688, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18073, UINT16_MAX, 9110, UINT16_MAX, 9110, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18075, 1693, UINT16_MAX, 1693, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18078, UINT16_MAX, 9111, UINT16_MAX, 9111, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18080, 1698, UINT16_MAX, 1698, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18083, UINT16_MAX, 9112, UINT16_MAX, 9112, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18085, 1703, UINT16_MAX, 1703, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18088, UINT16_MAX, 9113, UINT16_MAX, 9113, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18090, 1708, UINT16_MAX, 1708, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18093, UINT16_MAX, 9114, UINT16_MAX, 9114, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18095, 1713, UINT16_MAX, 1713, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18098, UINT16_MAX, 9115, UINT16_MAX, 9115, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18100, 1718, UINT16_MAX, 1718, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18103, UINT16_MAX, 9116, UINT16_MAX, 9116, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18105, 1723, UINT16_MAX, 1723, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18108, UINT16_MAX, 9117, UINT16_MAX, 9117, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18110, 1728, UINT16_MAX, 1728, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18113, UINT16_MAX, 9118, UINT16_MAX, 9118, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18115, 1733, UINT16_MAX, 1733, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18118, UINT16_MAX, 9119, UINT16_MAX, 9119, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18120, 1738, UINT16_MAX, 1738, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18123, UINT16_MAX, 9120, UINT16_MAX, 9120, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18125, 1743, UINT16_MAX, 1743, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18128, UINT16_MAX, 9121, UINT16_MAX, 9121, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18130, 1748, UINT16_MAX, 1748, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18133, UINT16_MAX, 9122, UINT16_MAX, 9122, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18135, 1753, UINT16_MAX, 1753, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18138, UINT16_MAX, 9123, UINT16_MAX, 9123, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18140, 1758, UINT16_MAX, 1758, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18143, UINT16_MAX, 9124, UINT16_MAX, 9124, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18145, 1763, UINT16_MAX, 1763, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18148, UINT16_MAX, 9125, UINT16_MAX, 9125, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18150, 1768, UINT16_MAX, 1768, UINT16_MAX, 3006, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18153, UINT16_MAX, 9126, UINT16_MAX, 9126, 3009, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18155, 1773, UINT16_MAX, 1773, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18158, UINT16_MAX, 9127, UINT16_MAX, 9127, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18160, 1778, UINT16_MAX, 1778, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18163, UINT16_MAX, 9128, UINT16_MAX, 9128, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18165, 1783, UINT16_MAX, 1783, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18168, UINT16_MAX, 9129, UINT16_MAX, 9129, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18170, 1788, UINT16_MAX, 1788, UINT16_MAX, 3024, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18173, UINT16_MAX, 9130, UINT16_MAX, 9130, 3027, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18175, 1793, UINT16_MAX, 1793, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18178, UINT16_MAX, 9131, UINT16_MAX, 9131, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18180, 1798, UINT16_MAX, 1798, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18183, UINT16_MAX, 9132, UINT16_MAX, 9132, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18185, 1803, UINT16_MAX, 1803, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18188, UINT16_MAX, 9133, UINT16_MAX, 9133, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18190, 1808, UINT16_MAX, 1808, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18193, UINT16_MAX, 9134, UINT16_MAX, 9134, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18195, 1813, UINT16_MAX, 1813, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18198, UINT16_MAX, 9135, UINT16_MAX, 9135, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18200, 1818, UINT16_MAX, 1818, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18203, UINT16_MAX, 9136, UINT16_MAX, 9136, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18205, 1823, UINT16_MAX, 1823, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18208, UINT16_MAX, 9137, UINT16_MAX, 9137, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18210, 1828, UINT16_MAX, 1828, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18213, UINT16_MAX, 9138, UINT16_MAX, 9138, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18215, 1833, UINT16_MAX, 1833, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18218, UINT16_MAX, 9139, UINT16_MAX, 9139, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18220, 1838, UINT16_MAX, 1838, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18223, UINT16_MAX, 9140, UINT16_MAX, 9140, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18225, 1843, UINT16_MAX, 1843, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18228, UINT16_MAX, 9141, UINT16_MAX, 9141, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18230, 1848, UINT16_MAX, 1848, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18233, UINT16_MAX, 9142, UINT16_MAX, 9142, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18235, 1853, UINT16_MAX, 1853, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18238, UINT16_MAX, 9143, UINT16_MAX, 9143, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18240, 1858, UINT16_MAX, 1858, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18243, UINT16_MAX, 9144, UINT16_MAX, 9144, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18245, 1863, UINT16_MAX, 1863, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18248, UINT16_MAX, 9145, UINT16_MAX, 9145, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18250, 1868, UINT16_MAX, 1868, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18253, UINT16_MAX, 9146, UINT16_MAX, 9146, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18255, 1873, UINT16_MAX, 1873, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18258, UINT16_MAX, 9147, UINT16_MAX, 9147, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18260, 1878, UINT16_MAX, 1878, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18263, UINT16_MAX, 9148, UINT16_MAX, 9148, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18265, 1883, UINT16_MAX, 1883, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18268, UINT16_MAX, 9149, UINT16_MAX, 9149, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18270, 1888, UINT16_MAX, 1888, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18273, UINT16_MAX, 9150, UINT16_MAX, 9150, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18275, 1893, UINT16_MAX, 1893, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18278, UINT16_MAX, 9151, UINT16_MAX, 9151, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18280, 1898, UINT16_MAX, 1898, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18283, UINT16_MAX, 9152, UINT16_MAX, 9152, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18285, 1903, UINT16_MAX, 1903, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18288, UINT16_MAX, 9153, UINT16_MAX, 9153, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18290, 1908, UINT16_MAX, 1908, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18293, UINT16_MAX, 9154, UINT16_MAX, 9154, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18295, 1913, UINT16_MAX, 1913, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18298, UINT16_MAX, 9155, UINT16_MAX, 9155, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18300, 18300, 9156, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18302, 18302, 9157, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18304, 18304, 9158, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18306, 18306, 9159, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 18308, 18308, 9160, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18310, 1783, 9129, UINT16_MAX, 9129, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9161, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9162, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 16514, UINT16_MAX, 9163, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9164, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18312, 1930, UINT16_MAX, 1930, UINT16_MAX, 3241, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18315, UINT16_MAX, 9165, UINT16_MAX, 9165, 3250, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18317, 1935, UINT16_MAX, 1935, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18320, UINT16_MAX, 9166, UINT16_MAX, 9166, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18322, 1940, UINT16_MAX, 1940, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18325, UINT16_MAX, 9167, UINT16_MAX, 9167, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18327, 1945, UINT16_MAX, 1945, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18330, UINT16_MAX, 9168, UINT16_MAX, 9168, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18332, 1950, UINT16_MAX, 1950, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18335, UINT16_MAX, 9169, UINT16_MAX, 9169, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18337, 1955, UINT16_MAX, 1955, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18340, UINT16_MAX, 9170, UINT16_MAX, 9170, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18342, 1960, UINT16_MAX, 1960, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18345, UINT16_MAX, 9171, UINT16_MAX, 9171, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18347, 1965, UINT16_MAX, 1965, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18350, UINT16_MAX, 9172, UINT16_MAX, 9172, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18352, 1970, UINT16_MAX, 1970, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18355, UINT16_MAX, 9173, UINT16_MAX, 9173, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18357, 1975, UINT16_MAX, 1975, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18360, UINT16_MAX, 9174, UINT16_MAX, 9174, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18362, 1980, UINT16_MAX, 1980, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18365, UINT16_MAX, 9175, UINT16_MAX, 9175, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18367, 1985, UINT16_MAX, 1985, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18370, UINT16_MAX, 9176, UINT16_MAX, 9176, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18372, 1990, UINT16_MAX, 1990, UINT16_MAX, 3455, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18375, UINT16_MAX, 9177, UINT16_MAX, 9177, 3458, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18377, 1995, UINT16_MAX, 1995, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18380, UINT16_MAX, 9178, UINT16_MAX, 9178, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18382, 2000, UINT16_MAX, 2000, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18385, UINT16_MAX, 9179, UINT16_MAX, 9179, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18387, 2005, UINT16_MAX, 2005, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18390, UINT16_MAX, 9180, UINT16_MAX, 9180, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18392, 2010, UINT16_MAX, 2010, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18395, UINT16_MAX, 9181, UINT16_MAX, 9181, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18397, 2015, UINT16_MAX, 2015, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18400, UINT16_MAX, 9182, UINT16_MAX, 9182, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18402, 2020, UINT16_MAX, 2020, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18405, UINT16_MAX, 9183, UINT16_MAX, 9183, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18407, 2025, UINT16_MAX, 2025, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18410, UINT16_MAX, 9184, UINT16_MAX, 9184, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18412, 2030, UINT16_MAX, 2030, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18415, UINT16_MAX, 9185, UINT16_MAX, 9185, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18417, 2035, UINT16_MAX, 2035, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18420, UINT16_MAX, 9186, UINT16_MAX, 9186, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18422, 2040, UINT16_MAX, 2040, UINT16_MAX, 3559, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18425, UINT16_MAX, 9187, UINT16_MAX, 9187, 3562, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18427, 2045, UINT16_MAX, 2045, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18430, UINT16_MAX, 9188, UINT16_MAX, 9188, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18432, 2050, UINT16_MAX, 2050, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18435, UINT16_MAX, 9189, UINT16_MAX, 9189, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18437, 2055, UINT16_MAX, 2055, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18440, UINT16_MAX, 9190, UINT16_MAX, 9190, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18442, 2060, UINT16_MAX, 2060, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18445, UINT16_MAX, 9191, UINT16_MAX, 9191, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18447, 2065, UINT16_MAX, 2065, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18450, UINT16_MAX, 9192, UINT16_MAX, 9192, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18452, 2070, UINT16_MAX, 2070, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18455, UINT16_MAX, 9193, UINT16_MAX, 9193, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18457, 2075, UINT16_MAX, 2075, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18460, UINT16_MAX, 9194, UINT16_MAX, 9194, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18462, 2080, UINT16_MAX, 2080, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18465, UINT16_MAX, 9195, UINT16_MAX, 9195, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18467, 2085, UINT16_MAX, 2085, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18470, UINT16_MAX, 9196, UINT16_MAX, 9196, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18472, 2090, UINT16_MAX, 2090, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18475, UINT16_MAX, 9197, UINT16_MAX, 9197, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18477, 2095, UINT16_MAX, 2095, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18480, UINT16_MAX, 9198, UINT16_MAX, 9198, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18482, 2100, UINT16_MAX, 2100, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18485, UINT16_MAX, 9199, UINT16_MAX, 9199, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18487, 2105, UINT16_MAX, 2105, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18490, UINT16_MAX, 9200, UINT16_MAX, 9200, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18492, 2110, UINT16_MAX, 2110, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18495, UINT16_MAX, 9201, UINT16_MAX, 9201, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18497, 2115, UINT16_MAX, 2115, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18500, UINT16_MAX, 9202, UINT16_MAX, 9202, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18502, 2120, UINT16_MAX, 2120, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18505, UINT16_MAX, 9203, UINT16_MAX, 9203, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18507, 2125, UINT16_MAX, 2125, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18510, UINT16_MAX, 9204, UINT16_MAX, 9204, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18512, 2130, UINT16_MAX, 2130, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18515, UINT16_MAX, 9205, UINT16_MAX, 9205, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18517, 2135, UINT16_MAX, 2135, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18520, UINT16_MAX, 9206, UINT16_MAX, 9206, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18522, 2140, UINT16_MAX, 2140, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18525, UINT16_MAX, 9207, UINT16_MAX, 9207, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18527, 2145, UINT16_MAX, 2145, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18530, UINT16_MAX, 9208, UINT16_MAX, 9208, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18532, 2150, UINT16_MAX, 2150, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18535, UINT16_MAX, 9209, UINT16_MAX, 9209, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2153, UINT16_MAX, 2153, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9210, UINT16_MAX, 9210, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2154, UINT16_MAX, 2154, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9211, UINT16_MAX, 9211, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2155, UINT16_MAX, 2155, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9212, UINT16_MAX, 9212, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18540, UINT16_MAX, 9213, UINT16_MAX, 9213, 3761, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18542, UINT16_MAX, 9214, UINT16_MAX, 9214, 3814, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18544, UINT16_MAX, 9215, UINT16_MAX, 9215, 4793, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18546, UINT16_MAX, 9216, UINT16_MAX, 9216, 4796, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18548, UINT16_MAX, 9217, UINT16_MAX, 9217, 4799, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18550, UINT16_MAX, 9218, UINT16_MAX, 9218, 4802, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18552, UINT16_MAX, 9219, UINT16_MAX, 9219, 4805, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18554, UINT16_MAX, 9220, UINT16_MAX, 9220, 4808, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18556, 2174, UINT16_MAX, 2174, UINT16_MAX, 3867, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18559, 2177, UINT16_MAX, 2177, UINT16_MAX, 3920, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18562, 2180, UINT16_MAX, 2180, UINT16_MAX, 4811, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18565, 2183, UINT16_MAX, 2183, UINT16_MAX, 4814, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18568, 2186, UINT16_MAX, 2186, UINT16_MAX, 4817, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18571, 2189, UINT16_MAX, 2189, UINT16_MAX, 4820, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18574, 2192, UINT16_MAX, 2192, UINT16_MAX, 4823, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18577, 2195, UINT16_MAX, 2195, UINT16_MAX, 4826, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18580, UINT16_MAX, 9221, UINT16_MAX, 9221, 3973, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18582, UINT16_MAX, 9222, UINT16_MAX, 9222, 3977, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18584, UINT16_MAX, 9223, UINT16_MAX, 9223, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18586, UINT16_MAX, 9224, UINT16_MAX, 9224, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18588, UINT16_MAX, 9225, UINT16_MAX, 9225, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18590, UINT16_MAX, 9226, UINT16_MAX, 9226, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18592, 2210, UINT16_MAX, 2210, UINT16_MAX, 3981, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18595, 2213, UINT16_MAX, 2213, UINT16_MAX, 3985, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18598, 2216, UINT16_MAX, 2216, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18601, 2219, UINT16_MAX, 2219, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18604, 2222, UINT16_MAX, 2222, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18607, 2225, UINT16_MAX, 2225, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18610, UINT16_MAX, 9227, UINT16_MAX, 9227, 3989, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18612, UINT16_MAX, 9228, UINT16_MAX, 9228, 4042, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18614, UINT16_MAX, 9229, UINT16_MAX, 9229, 4829, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18616, UINT16_MAX, 9230, UINT16_MAX, 9230, 4832, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18618, UINT16_MAX, 9231, UINT16_MAX, 9231, 4835, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18620, UINT16_MAX, 9232, UINT16_MAX, 9232, 4838, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18622, UINT16_MAX, 9233, UINT16_MAX, 9233, 4841, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18624, UINT16_MAX, 9234, UINT16_MAX, 9234, 4844, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18626, 2244, UINT16_MAX, 2244, UINT16_MAX, 4095, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18629, 2247, UINT16_MAX, 2247, UINT16_MAX, 4148, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18632, 2250, UINT16_MAX, 2250, UINT16_MAX, 4847, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18635, 2253, UINT16_MAX, 2253, UINT16_MAX, 4850, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18638, 2256, UINT16_MAX, 2256, UINT16_MAX, 4853, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18641, 2259, UINT16_MAX, 2259, UINT16_MAX, 4856, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18644, 2262, UINT16_MAX, 2262, UINT16_MAX, 4859, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18647, 2265, UINT16_MAX, 2265, UINT16_MAX, 4862, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18650, UINT16_MAX, 9235, UINT16_MAX, 9235, 4201, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18652, UINT16_MAX, 9236, UINT16_MAX, 9236, 4253, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18654, UINT16_MAX, 9237, UINT16_MAX, 9237, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18656, UINT16_MAX, 9238, UINT16_MAX, 9238, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18658, UINT16_MAX, 9239, UINT16_MAX, 9239, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18660, UINT16_MAX, 9240, UINT16_MAX, 9240, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18662, UINT16_MAX, 9241, UINT16_MAX, 9241, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18664, UINT16_MAX, 9242, UINT16_MAX, 9242, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18666, 2284, UINT16_MAX, 2284, UINT16_MAX, 4305, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18669, 2287, UINT16_MAX, 2287, UINT16_MAX, 4357, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18672, 2290, UINT16_MAX, 2290, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18675, 2293, UINT16_MAX, 2293, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18678, 2296, UINT16_MAX, 2296, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18681, 2299, UINT16_MAX, 2299, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18684, 2302, UINT16_MAX, 2302, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18687, 2305, UINT16_MAX, 2305, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18690, UINT16_MAX, 9243, UINT16_MAX, 9243, 4409, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18692, UINT16_MAX, 9244, UINT16_MAX, 9244, 4413, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18694, UINT16_MAX, 9245, UINT16_MAX, 9245, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18696, UINT16_MAX, 9246, UINT16_MAX, 9246, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18698, UINT16_MAX, 9247, UINT16_MAX, 9247, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18700, UINT16_MAX, 9248, UINT16_MAX, 9248, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18702, 2320, UINT16_MAX, 2320, UINT16_MAX, 4417, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18705, 2323, UINT16_MAX, 2323, UINT16_MAX, 4421, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18708, 2326, UINT16_MAX, 2326, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18711, 2329, UINT16_MAX, 2329, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18714, 2332, UINT16_MAX, 2332, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18717, 2335, UINT16_MAX, 2335, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18720, 18720, 9249, UINT16_MAX, UINT16_MAX, 4425, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18722, UINT16_MAX, 9250, UINT16_MAX, 9250, 4477, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18724, 35110, 9251, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18729, UINT16_MAX, 9252, UINT16_MAX, 9252, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18731, 35117, 9253, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18736, UINT16_MAX, 9254, UINT16_MAX, 9254, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18738, 35124, 9255, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18743, UINT16_MAX, 9256, UINT16_MAX, 9256, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18745, 2363, UINT16_MAX, 2363, UINT16_MAX, 4529, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18748, 2366, UINT16_MAX, 2366, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18751, 2369, UINT16_MAX, 2369, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18754, 2372, UINT16_MAX, 2372, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18757, UINT16_MAX, 9257, UINT16_MAX, 9257, 4581, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18759, UINT16_MAX, 9258, UINT16_MAX, 9258, 4634, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18761, UINT16_MAX, 9259, UINT16_MAX, 9259, 4865, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18763, UINT16_MAX, 9260, UINT16_MAX, 9260, 4868, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18765, UINT16_MAX, 9261, UINT16_MAX, 9261, 4871, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18767, UINT16_MAX, 9262, UINT16_MAX, 9262, 4874, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18769, UINT16_MAX, 9263, UINT16_MAX, 9263, 4877, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18771, UINT16_MAX, 9264, UINT16_MAX, 9264, 4880, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18773, 2391, UINT16_MAX, 2391, UINT16_MAX, 4687, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18776, 2394, UINT16_MAX, 2394, UINT16_MAX, 4740, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18779, 2397, UINT16_MAX, 2397, UINT16_MAX, 4883, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18782, 2400, UINT16_MAX, 2400, UINT16_MAX, 4886, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18785, 2403, UINT16_MAX, 2403, UINT16_MAX, 4889, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18788, 2406, UINT16_MAX, 2406, UINT16_MAX, 4892, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18791, 2409, UINT16_MAX, 2409, UINT16_MAX, 4895, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18794, 2412, UINT16_MAX, 2412, UINT16_MAX, 4898, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18797, UINT16_MAX, 9265, UINT16_MAX, 9265, 4901, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 820, UINT16_MAX, 9266, UINT16_MAX, 9266, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18799, UINT16_MAX, 9267, UINT16_MAX, 9267, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 824, UINT16_MAX, 9268, UINT16_MAX, 9268, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18801, UINT16_MAX, 9269, UINT16_MAX, 9269, 4910, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 827, UINT16_MAX, 9270, UINT16_MAX, 9270, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18803, UINT16_MAX, 9271, UINT16_MAX, 9271, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 830, UINT16_MAX, 9272, UINT16_MAX, 9272, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18805, UINT16_MAX, 9273, UINT16_MAX, 9273, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 833, UINT16_MAX, 9274, UINT16_MAX, 9274, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18807, UINT16_MAX, 9275, UINT16_MAX, 9275, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 836, UINT16_MAX, 9276, UINT16_MAX, 9276, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18809, UINT16_MAX, 9277, UINT16_MAX, 9277, 5030, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 839, UINT16_MAX, 9278, UINT16_MAX, 9278, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18811, 18813, 9279, UINT16_MAX, 9279, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18815, 18817, 9280, UINT16_MAX, 9280, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18819, 18821, 9281, UINT16_MAX, 9281, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18823, 18825, 9282, UINT16_MAX, 9282, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18827, 18829, 9283, UINT16_MAX, 9283, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18831, 18833, 9284, UINT16_MAX, 9284, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18835, 18837, 9285, UINT16_MAX, 9285, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18839, 18841, 9286, UINT16_MAX, 9286, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18843, 18813, UINT16_MAX, 9287, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18845, 18817, UINT16_MAX, 9288, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18847, 18821, UINT16_MAX, 9289, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18849, 18825, UINT16_MAX, 9290, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18851, 18829, UINT16_MAX, 9291, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18853, 18833, UINT16_MAX, 9292, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18855, 18837, UINT16_MAX, 9293, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18857, 18841, UINT16_MAX, 9294, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18859, 18861, 9295, UINT16_MAX, 9295, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18863, 18865, 9296, UINT16_MAX, 9296, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18867, 18869, 9297, UINT16_MAX, 9297, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18871, 18873, 9298, UINT16_MAX, 9298, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18875, 18877, 9299, UINT16_MAX, 9299, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18879, 18881, 9300, UINT16_MAX, 9300, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18883, 18885, 9301, UINT16_MAX, 9301, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18887, 18889, 9302, UINT16_MAX, 9302, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18891, 18861, UINT16_MAX, 9303, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18893, 18865, UINT16_MAX, 9304, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18895, 18869, UINT16_MAX, 9305, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18897, 18873, UINT16_MAX, 9306, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18899, 18877, UINT16_MAX, 9307, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18901, 18881, UINT16_MAX, 9308, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18903, 18885, UINT16_MAX, 9309, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18905, 18889, UINT16_MAX, 9310, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18907, 18909, 9311, UINT16_MAX, 9311, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18911, 18913, 9312, UINT16_MAX, 9312, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18915, 18917, 9313, UINT16_MAX, 9313, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18919, 18921, 9314, UINT16_MAX, 9314, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18923, 18925, 9315, UINT16_MAX, 9315, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18927, 18929, 9316, UINT16_MAX, 9316, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18931, 18933, 9317, UINT16_MAX, 9317, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18935, 18937, 9318, UINT16_MAX, 9318, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18939, 18909, UINT16_MAX, 9319, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18941, 18913, UINT16_MAX, 9320, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18943, 18917, UINT16_MAX, 9321, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18945, 18921, UINT16_MAX, 9322, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18947, 18925, UINT16_MAX, 9323, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18949, 18929, UINT16_MAX, 9324, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18951, 18933, UINT16_MAX, 9325, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18953, 18937, UINT16_MAX, 9326, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18955, UINT16_MAX, 9327, UINT16_MAX, 9327, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18957, UINT16_MAX, 9328, UINT16_MAX, 9328, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18959, 18961, 9329, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18963, 18965, 9330, UINT16_MAX, 9330, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18967, 18969, 9331, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18971, 18971, 9332, UINT16_MAX, UINT16_MAX, 4907, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18973, 35359, 9333, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18978, 2596, UINT16_MAX, 2596, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18981, 2599, UINT16_MAX, 2599, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 18984, 2602, UINT16_MAX, 2602, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2603, 2604, UINT16_MAX, 2604, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 18989, 18965, UINT16_MAX, 9334, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 18991, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 807, 807, 7437, UINT16_MAX, 7437, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 18991, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 4919, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 18993, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 18995, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 18997, 18999, 9335, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19001, 19003, 9336, UINT16_MAX, 9336, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19005, 19007, 9337, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19009, 19009, 9338, UINT16_MAX, UINT16_MAX, 4916, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19011, 35397, 9339, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19016, 2634, UINT16_MAX, 2634, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2635, 2636, UINT16_MAX, 2636, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19021, 2639, UINT16_MAX, 2639, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2640, 2641, UINT16_MAX, 2641, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 19026, 19003, UINT16_MAX, 9340, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19028, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19030, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19032, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19034, UINT16_MAX, 9341, UINT16_MAX, 9341, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19036, UINT16_MAX, 9342, UINT16_MAX, 9342, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19038, 35424, 9343, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 2659, 33610, 9344, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19044, 19044, 9345, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19046, 35432, 9346, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19051, 2669, UINT16_MAX, 2669, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19054, 2672, UINT16_MAX, 2672, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19057, 2675, UINT16_MAX, 2675, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2676, 2677, UINT16_MAX, 2677, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19062, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19064, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19066, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19068, UINT16_MAX, 9347, UINT16_MAX, 9347, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19070, UINT16_MAX, 9348, UINT16_MAX, 9348, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19072, 35458, 9349, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 2693, 33651, 9350, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19078, 19078, 9351, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19080, UINT16_MAX, 9352, UINT16_MAX, 9352, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19082, 19082, 9353, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19084, 35470, 9354, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19089, 2707, UINT16_MAX, 2707, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19092, 2710, UINT16_MAX, 2710, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19095, 2713, UINT16_MAX, 2713, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2714, 2715, UINT16_MAX, 2715, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19100, 2718, UINT16_MAX, 2718, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19103, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 2721, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 2722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19107, 19109, 9355, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19111, 19113, 9356, UINT16_MAX, 9356, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19115, 19117, 9357, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19119, 19119, 9358, UINT16_MAX, UINT16_MAX, 5036, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, 19121, 35507, 9359, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19126, 2744, UINT16_MAX, 2744, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2745, 2746, UINT16_MAX, 2746, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 19131, 2749, UINT16_MAX, 2749, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2750, 2751, UINT16_MAX, 2751, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, 19136, 19113, UINT16_MAX, 9360, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, 2754, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19139, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 4971, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, 2757, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, 2758, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_COMPAT, 26, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_NOBREAK, 26, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_ZWJ}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NOBREAK, 2759, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19144, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PI, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PF, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 2762, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19147, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ZL, 0, UTF8PROC_BIDI_CLASS_WS, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_ZP, 0, UTF8PROC_BIDI_CLASS_B, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_LRE, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_RLE, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_PDF, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_LRO, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_RLO, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, 19152, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, 35538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19157, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35543, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19162, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19164, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_CS, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19166, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19168, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19170, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 51940, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_LRI, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_RLI, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_FSI, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_PDI, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 8, UINT16_MAX, 9361, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, 2799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUPER, 2800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUPER, 2801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 2802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 2803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 2804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 13, UINT16_MAX, 9362, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 38, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 31, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 32, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, 2799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUB, 2800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUB, 2801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, 2802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, 2803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, 2804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 0, UINT16_MAX, 9363, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 4, UINT16_MAX, 9364, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 14, UINT16_MAX, 9365, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 23, UINT16_MAX, 9366, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 485, UINT16_MAX, 9367, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 7, UINT16_MAX, 9368, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 10, UINT16_MAX, 9369, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 11, UINT16_MAX, 9370, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 12, UINT16_MAX, 9371, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 13, UINT16_MAX, 9372, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 15, UINT16_MAX, 9373, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 18, UINT16_MAX, 9374, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 19, UINT16_MAX, 9375, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, 19189, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35578, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 9376, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19198, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2822, UINT16_MAX, UINT16_MAX, 9377, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19207, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 9378, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 9379, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 9380, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 9381, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 9382, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 277, UINT16_MAX, 9383, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 9384, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 9385, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 9386, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 9387, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 9388, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19209, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 9389, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 9390, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 9391, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 9392, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 9393, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 19212, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 19217, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 9394, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2836, 866, UINT16_MAX, 866, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 9395, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 1501, 10, UINT16_MAX, 10, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, 2837, 65, UINT16_MAX, 65, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 9396, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 9397, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 9398, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 9399, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 9400, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2839, UINT16_MAX, 2839, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 9401, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 9402, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2840, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2841, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2842, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2843, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 9403, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35612, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 858, UINT16_MAX, 9404, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 847, UINT16_MAX, 9405, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2847, UINT16_MAX, UINT16_MAX, 9406, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2848, UINT16_MAX, UINT16_MAX, 9407, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FONT, 2849, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 9408, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 9409, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 9410, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 9411, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 9412, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9413, UINT16_MAX, 9413, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 52008, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35632, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35638, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35641, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35644, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35647, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35650, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35653, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35662, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 19281, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 1499, 2899, UINT16_MAX, 2899, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19284, 2902, UINT16_MAX, 2902, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35671, 2906, UINT16_MAX, 2906, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19291, 2909, UINT16_MAX, 2909, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2910, 2911, UINT16_MAX, 2911, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19296, 2914, UINT16_MAX, 2914, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35683, 2918, UINT16_MAX, 2918, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 52071, 2924, UINT16_MAX, 2924, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19309, 2927, UINT16_MAX, 2927, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2928, 2929, UINT16_MAX, 2929, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19314, 2932, UINT16_MAX, 2932, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35701, 2936, UINT16_MAX, 2936, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 1502, 2937, UINT16_MAX, 2937, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2813, 2938, UINT16_MAX, 2938, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 1494, 2939, UINT16_MAX, 2939, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 1503, 2940, UINT16_MAX, 2940, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 8, UINT16_MAX, 9414, UINT16_MAX, 9414, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19325, UINT16_MAX, 9415, UINT16_MAX, 9415, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35711, UINT16_MAX, 9416, UINT16_MAX, 9416, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19330, UINT16_MAX, 9417, UINT16_MAX, 9417, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21, UINT16_MAX, 9418, UINT16_MAX, 9418, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19332, UINT16_MAX, 9419, UINT16_MAX, 9419, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35718, UINT16_MAX, 9420, UINT16_MAX, 9420, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 52105, UINT16_MAX, 9421, UINT16_MAX, 9421, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19342, UINT16_MAX, 9422, UINT16_MAX, 9422, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 23, UINT16_MAX, 9423, UINT16_MAX, 9423, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 19344, UINT16_MAX, 9424, UINT16_MAX, 9424, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35730, UINT16_MAX, 9425, UINT16_MAX, 9425, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 11, UINT16_MAX, 9426, UINT16_MAX, 9426, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 2, UINT16_MAX, 9427, UINT16_MAX, 9427, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3, UINT16_MAX, 9428, UINT16_MAX, 9428, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 12, UINT16_MAX, 9429, UINT16_MAX, 9429, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 2965, UINT16_MAX, 2965, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9430, UINT16_MAX, 9430, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, 35734, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5039, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5042, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5045, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19353, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19355, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19357, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19359, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19361, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19363, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5048, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5054, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5051, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5057, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19365, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5060, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19367, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5063, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19369, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5066, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19371, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5069, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19373, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19375, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35761, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19380, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35766, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5072, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19385, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5075, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19387, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5078, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19389, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5081, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19391, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5090, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19393, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5087, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19395, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5099, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5102, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19397, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19399, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19401, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19403, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19405, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5105, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5108, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19407, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19409, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5111, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5114, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19411, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19413, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5117, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5120, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5147, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5150, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19415, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19417, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5123, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5126, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19419, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19421, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5129, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5132, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19423, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19425, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5153, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5156, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5135, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5138, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5141, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5144, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19427, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19429, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19431, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19433, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5159, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5162, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5165, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5168, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19435, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19437, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19439, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19441, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19445, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19447, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19449, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, 3067, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, 3068, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 38, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 31, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 32, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19453, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19455, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19457, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19459, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19461, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19463, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19465, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19467, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19469, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19471, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 19473, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 35883, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52270, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52275, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52280, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52285, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52290, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52295, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52300, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52305, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52310, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52315, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52320, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19557, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19559, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19561, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19563, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19565, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19567, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19569, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 19573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35959, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35962, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35965, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35968, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35971, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35974, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35977, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35980, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35983, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35986, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 35989, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35992, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35995, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 35998, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36001, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36004, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36007, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36010, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36013, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36016, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36019, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36022, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36025, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36028, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36031, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36034, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36037, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36040, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36043, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36046, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36049, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36052, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36055, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36058, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36061, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36064, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36067, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1491, 3302, UINT16_MAX, 3302, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1493, 3303, UINT16_MAX, 3303, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2813, 3304, UINT16_MAX, 3304, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1494, 3305, UINT16_MAX, 3305, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1495, 3306, UINT16_MAX, 3306, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2838, 3307, UINT16_MAX, 3307, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1497, 3308, UINT16_MAX, 3308, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1498, 3309, UINT16_MAX, 3309, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1499, 3310, UINT16_MAX, 3310, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1500, 3311, UINT16_MAX, 3311, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1501, 3312, UINT16_MAX, 3312, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1502, 3313, UINT16_MAX, 3313, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1503, 3314, UINT16_MAX, 3314, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1504, 3315, UINT16_MAX, 3315, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1505, 3316, UINT16_MAX, 3316, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1507, 3317, UINT16_MAX, 3317, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2827, 3318, UINT16_MAX, 3318, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1508, 3319, UINT16_MAX, 3319, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3320, 3321, UINT16_MAX, 3321, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1509, 3322, UINT16_MAX, 3322, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1510, 3323, UINT16_MAX, 3323, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2910, 3324, UINT16_MAX, 3324, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1511, 3325, UINT16_MAX, 3325, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2928, 3326, UINT16_MAX, 3326, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3327, 3328, UINT16_MAX, 3328, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2835, 3329, UINT16_MAX, 3329, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 0, UINT16_MAX, 9431, UINT16_MAX, 9431, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1, UINT16_MAX, 9432, UINT16_MAX, 9432, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2, UINT16_MAX, 9433, UINT16_MAX, 9433, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3, UINT16_MAX, 9434, UINT16_MAX, 9434, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4, UINT16_MAX, 9435, UINT16_MAX, 9435, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 5, UINT16_MAX, 9436, UINT16_MAX, 9436, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 6, UINT16_MAX, 9437, UINT16_MAX, 9437, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 7, UINT16_MAX, 9438, UINT16_MAX, 9438, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 8, UINT16_MAX, 9439, UINT16_MAX, 9439, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 9, UINT16_MAX, 9440, UINT16_MAX, 9440, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 10, UINT16_MAX, 9441, UINT16_MAX, 9441, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 11, UINT16_MAX, 9442, UINT16_MAX, 9442, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 12, UINT16_MAX, 9443, UINT16_MAX, 9443, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 13, UINT16_MAX, 9444, UINT16_MAX, 9444, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 14, UINT16_MAX, 9445, UINT16_MAX, 9445, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 15, UINT16_MAX, 9446, UINT16_MAX, 9446, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 16, UINT16_MAX, 9447, UINT16_MAX, 9447, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 17, UINT16_MAX, 9448, UINT16_MAX, 9448, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 18, UINT16_MAX, 9449, UINT16_MAX, 9449, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 19, UINT16_MAX, 9450, UINT16_MAX, 9450, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20, UINT16_MAX, 9451, UINT16_MAX, 9451, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 21, UINT16_MAX, 9452, UINT16_MAX, 9452, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 22, UINT16_MAX, 9453, UINT16_MAX, 9453, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 23, UINT16_MAX, 9454, UINT16_MAX, 9454, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 24, UINT16_MAX, 9455, UINT16_MAX, 9455, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 25, UINT16_MAX, 9456, UINT16_MAX, 9456, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 2793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 52482, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 36103, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 19722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 36108, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, 19727, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5171, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3345, UINT16_MAX, 3345, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3346, UINT16_MAX, 3346, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3347, UINT16_MAX, 3347, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3348, UINT16_MAX, 3348, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3349, UINT16_MAX, 3349, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3350, UINT16_MAX, 3350, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3351, UINT16_MAX, 3351, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3352, UINT16_MAX, 3352, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3353, UINT16_MAX, 3353, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3354, UINT16_MAX, 3354, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3355, UINT16_MAX, 3355, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3356, UINT16_MAX, 3356, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3357, UINT16_MAX, 3357, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3358, UINT16_MAX, 3358, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3359, UINT16_MAX, 3359, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3360, UINT16_MAX, 3360, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3361, UINT16_MAX, 3361, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3362, UINT16_MAX, 3362, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3363, UINT16_MAX, 3363, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3364, UINT16_MAX, 3364, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3365, UINT16_MAX, 3365, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3366, UINT16_MAX, 3366, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3367, UINT16_MAX, 3367, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3368, UINT16_MAX, 3368, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3369, UINT16_MAX, 3369, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3370, UINT16_MAX, 3370, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3371, UINT16_MAX, 3371, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3372, UINT16_MAX, 3372, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3373, UINT16_MAX, 3373, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3374, UINT16_MAX, 3374, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3375, UINT16_MAX, 3375, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3376, UINT16_MAX, 3376, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3377, UINT16_MAX, 3377, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3378, UINT16_MAX, 3378, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3379, UINT16_MAX, 3379, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3380, UINT16_MAX, 3380, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3381, UINT16_MAX, 3381, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3382, UINT16_MAX, 3382, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3383, UINT16_MAX, 3383, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3384, UINT16_MAX, 3384, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3385, UINT16_MAX, 3385, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3386, UINT16_MAX, 3386, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3387, UINT16_MAX, 3387, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3388, UINT16_MAX, 3388, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3389, UINT16_MAX, 3389, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3390, UINT16_MAX, 3390, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3391, UINT16_MAX, 3391, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3392, UINT16_MAX, 3392, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9457, UINT16_MAX, 9457, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9458, UINT16_MAX, 9458, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9459, UINT16_MAX, 9459, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9460, UINT16_MAX, 9460, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9461, UINT16_MAX, 9461, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9462, UINT16_MAX, 9462, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9463, UINT16_MAX, 9463, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9464, UINT16_MAX, 9464, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9465, UINT16_MAX, 9465, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9466, UINT16_MAX, 9466, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9467, UINT16_MAX, 9467, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9468, UINT16_MAX, 9468, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9469, UINT16_MAX, 9469, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9470, UINT16_MAX, 9470, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9471, UINT16_MAX, 9471, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9472, UINT16_MAX, 9472, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9473, UINT16_MAX, 9473, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9474, UINT16_MAX, 9474, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9475, UINT16_MAX, 9475, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9476, UINT16_MAX, 9476, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9477, UINT16_MAX, 9477, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9478, UINT16_MAX, 9478, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9479, UINT16_MAX, 9479, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9480, UINT16_MAX, 9480, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9481, UINT16_MAX, 9481, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9482, UINT16_MAX, 9482, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9483, UINT16_MAX, 9483, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9484, UINT16_MAX, 9484, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9485, UINT16_MAX, 9485, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9486, UINT16_MAX, 9486, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9487, UINT16_MAX, 9487, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9488, UINT16_MAX, 9488, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9489, UINT16_MAX, 9489, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9490, UINT16_MAX, 9490, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9491, UINT16_MAX, 9491, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9492, UINT16_MAX, 9492, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9493, UINT16_MAX, 9493, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9494, UINT16_MAX, 9494, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9495, UINT16_MAX, 9495, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9496, UINT16_MAX, 9496, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9497, UINT16_MAX, 9497, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9498, UINT16_MAX, 9498, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9499, UINT16_MAX, 9499, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9500, UINT16_MAX, 9500, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9501, UINT16_MAX, 9501, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9502, UINT16_MAX, 9502, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9503, UINT16_MAX, 9503, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9504, UINT16_MAX, 9504, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3393, UINT16_MAX, 3393, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9505, UINT16_MAX, 9505, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3394, UINT16_MAX, 3394, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3395, UINT16_MAX, 3395, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3396, UINT16_MAX, 3396, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9506, UINT16_MAX, 9506, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9507, UINT16_MAX, 9507, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3397, UINT16_MAX, 3397, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9508, UINT16_MAX, 9508, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3398, UINT16_MAX, 3398, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9509, UINT16_MAX, 9509, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3399, UINT16_MAX, 3399, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9510, UINT16_MAX, 9510, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1513, UINT16_MAX, 1513, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1531, UINT16_MAX, 1531, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1512, UINT16_MAX, 1512, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1520, UINT16_MAX, 1520, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7083, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3400, UINT16_MAX, 3400, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9511, UINT16_MAX, 9511, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9512, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3401, UINT16_MAX, 3401, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9513, UINT16_MAX, 9513, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9514, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9515, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9516, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9517, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9518, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 9, UINT16_MAX, 9519, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 2910, UINT16_MAX, 9520, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3402, UINT16_MAX, 3402, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3403, UINT16_MAX, 3403, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3404, UINT16_MAX, 3404, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9521, UINT16_MAX, 9521, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3405, UINT16_MAX, 3405, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9522, UINT16_MAX, 9522, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3406, UINT16_MAX, 3406, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9523, UINT16_MAX, 9523, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3407, UINT16_MAX, 3407, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9524, UINT16_MAX, 9524, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3408, UINT16_MAX, 3408, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9525, UINT16_MAX, 9525, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3409, UINT16_MAX, 3409, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9526, UINT16_MAX, 9526, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3410, UINT16_MAX, 3410, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9527, UINT16_MAX, 9527, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3411, UINT16_MAX, 3411, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9528, UINT16_MAX, 9528, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3412, UINT16_MAX, 3412, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9529, UINT16_MAX, 9529, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3413, UINT16_MAX, 3413, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9530, UINT16_MAX, 9530, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3414, UINT16_MAX, 3414, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9531, UINT16_MAX, 9531, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3415, UINT16_MAX, 3415, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9532, UINT16_MAX, 9532, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3416, UINT16_MAX, 3416, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9533, UINT16_MAX, 9533, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3417, UINT16_MAX, 3417, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9534, UINT16_MAX, 9534, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3418, UINT16_MAX, 3418, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9535, UINT16_MAX, 9535, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3419, UINT16_MAX, 3419, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9536, UINT16_MAX, 9536, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3420, UINT16_MAX, 3420, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9537, UINT16_MAX, 9537, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3421, UINT16_MAX, 3421, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9538, UINT16_MAX, 9538, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3422, UINT16_MAX, 3422, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9539, UINT16_MAX, 9539, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3423, UINT16_MAX, 3423, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9540, UINT16_MAX, 9540, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3424, UINT16_MAX, 3424, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9541, UINT16_MAX, 9541, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3425, UINT16_MAX, 3425, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9542, UINT16_MAX, 9542, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3426, UINT16_MAX, 3426, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9543, UINT16_MAX, 9543, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3427, UINT16_MAX, 3427, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9544, UINT16_MAX, 9544, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3428, UINT16_MAX, 3428, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9545, UINT16_MAX, 9545, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3429, UINT16_MAX, 3429, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9546, UINT16_MAX, 9546, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3430, UINT16_MAX, 3430, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9547, UINT16_MAX, 9547, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3431, UINT16_MAX, 3431, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9548, UINT16_MAX, 9548, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3432, UINT16_MAX, 3432, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9549, UINT16_MAX, 9549, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3433, UINT16_MAX, 3433, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9550, UINT16_MAX, 9550, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3434, UINT16_MAX, 3434, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9551, UINT16_MAX, 9551, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3435, UINT16_MAX, 3435, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9552, UINT16_MAX, 9552, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3436, UINT16_MAX, 3436, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9553, UINT16_MAX, 9553, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3437, UINT16_MAX, 3437, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9554, UINT16_MAX, 9554, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3438, UINT16_MAX, 3438, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9555, UINT16_MAX, 9555, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3439, UINT16_MAX, 3439, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9556, UINT16_MAX, 9556, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3440, UINT16_MAX, 3440, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9557, UINT16_MAX, 9557, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3441, UINT16_MAX, 3441, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9558, UINT16_MAX, 9558, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3442, UINT16_MAX, 3442, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9559, UINT16_MAX, 9559, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3443, UINT16_MAX, 3443, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9560, UINT16_MAX, 9560, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3444, UINT16_MAX, 3444, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9561, UINT16_MAX, 9561, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3445, UINT16_MAX, 3445, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9562, UINT16_MAX, 9562, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3446, UINT16_MAX, 3446, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9563, UINT16_MAX, 9563, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3447, UINT16_MAX, 3447, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9564, UINT16_MAX, 9564, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3448, UINT16_MAX, 3448, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9565, UINT16_MAX, 9565, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3449, UINT16_MAX, 3449, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9566, UINT16_MAX, 9566, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3450, UINT16_MAX, 3450, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9567, UINT16_MAX, 9567, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3451, UINT16_MAX, 3451, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9568, UINT16_MAX, 9568, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3452, UINT16_MAX, 3452, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9569, UINT16_MAX, 9569, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3453, UINT16_MAX, 3453, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9570, UINT16_MAX, 9570, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9571, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3454, UINT16_MAX, 3454, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9572, UINT16_MAX, 9572, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3455, UINT16_MAX, 3455, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9573, UINT16_MAX, 9573, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 3456, UINT16_MAX, 3456, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9574, UINT16_MAX, 9574, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9575, UINT16_MAX, 9575, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9576, UINT16_MAX, 9576, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9577, UINT16_MAX, 9577, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9578, UINT16_MAX, 9578, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9579, UINT16_MAX, 9579, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9580, UINT16_MAX, 9580, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9581, UINT16_MAX, 9581, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9582, UINT16_MAX, 9582, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9583, UINT16_MAX, 9583, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9584, UINT16_MAX, 9584, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9585, UINT16_MAX, 9585, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9586, UINT16_MAX, 9586, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9587, UINT16_MAX, 9587, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9588, UINT16_MAX, 9588, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9589, UINT16_MAX, 9589, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9590, UINT16_MAX, 9590, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9591, UINT16_MAX, 9591, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9592, UINT16_MAX, 9592, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9593, UINT16_MAX, 9593, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9594, UINT16_MAX, 9594, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9595, UINT16_MAX, 9595, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9596, UINT16_MAX, 9596, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9597, UINT16_MAX, 9597, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9598, UINT16_MAX, 9598, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9599, UINT16_MAX, 9599, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9600, UINT16_MAX, 9600, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9601, UINT16_MAX, 9601, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9602, UINT16_MAX, 9602, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9603, UINT16_MAX, 9603, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9604, UINT16_MAX, 9604, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9605, UINT16_MAX, 9605, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9606, UINT16_MAX, 9606, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9607, UINT16_MAX, 9607, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9608, UINT16_MAX, 9608, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9609, UINT16_MAX, 9609, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9610, UINT16_MAX, 9610, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9611, UINT16_MAX, 9611, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9612, UINT16_MAX, 9612, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9613, UINT16_MAX, 9613, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9614, UINT16_MAX, 9614, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3457, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3458, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3459, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3460, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3461, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3462, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3463, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3464, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3465, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3467, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3469, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3470, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3471, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3472, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3473, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3474, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3475, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3476, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3477, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3478, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3479, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3480, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3481, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3482, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3483, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3484, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3485, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3486, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3487, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3488, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3489, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3490, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3491, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3492, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3493, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3494, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3495, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3496, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3498, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3499, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3500, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3501, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3503, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3512, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3513, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3515, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3519, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3521, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3522, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3523, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3524, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3525, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3527, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3528, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3529, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3531, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3535, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3539, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3541, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3542, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3543, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3544, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3545, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3546, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3547, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3548, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3549, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3550, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3551, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3552, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3553, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3554, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3555, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3556, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3557, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3559, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3560, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3561, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3562, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3563, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3564, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3565, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3566, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3567, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3568, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3569, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3570, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3572, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3574, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3578, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3580, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3586, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3606, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3607, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3608, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3610, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3612, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3614, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3616, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3620, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3622, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3624, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3627, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3628, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3630, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3631, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3632, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3633, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3634, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3636, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3637, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3638, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3639, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3640, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3641, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3642, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3643, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3644, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3645, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3646, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3647, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3648, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3649, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3650, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3651, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3652, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3653, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3654, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3655, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3657, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3658, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3660, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3661, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3662, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3663, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3664, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3665, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3666, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3667, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3669, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3670, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3671, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_WIDE, 26, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MC, 224, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 3674, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3483, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5239, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5174, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20061, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5177, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20063, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5180, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20065, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5183, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20067, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5186, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20069, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5189, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20071, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5192, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20073, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5195, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20075, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5198, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20077, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5201, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20079, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5204, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20081, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5207, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20083, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5210, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20085, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5213, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20087, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5216, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20089, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5219, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20091, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20093, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5223, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20095, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20097, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5227, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20099, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20101, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5231, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20103, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20105, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5235, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20107, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20109, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20111, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 8, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32820, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 8, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 32821, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 20113, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 20115, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5242, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, 20117, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_VERTICAL, 20119, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5310, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5245, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20121, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5248, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20123, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5251, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20125, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5254, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20127, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5257, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20129, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5260, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20131, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5263, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20133, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5266, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20135, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5269, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20137, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5272, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20139, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5275, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20141, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5278, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20143, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5281, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20145, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5284, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20147, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5287, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20149, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5290, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20151, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20153, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5294, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20155, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20157, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5298, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20159, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20161, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5302, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20163, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20165, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5306, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20167, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20169, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5313, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5316, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5319, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5322, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20171, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20173, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20175, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20177, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 20179, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5325, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, 20181, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_VERTICAL, 20183, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3805, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3806, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3808, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3809, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3810, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3811, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3812, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3813, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3815, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3816, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3817, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3818, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3820, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3821, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3822, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3823, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3824, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3825, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3826, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3827, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3828, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3829, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3830, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3831, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3832, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3833, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3834, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3835, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3836, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3837, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3838, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3839, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3840, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3841, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3842, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3843, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3844, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3845, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3846, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3847, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3848, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3849, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3850, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3851, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3854, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3855, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3857, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3860, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3861, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3863, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3864, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3866, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3867, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3869, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3872, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3873, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3875, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3876, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3879, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3881, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3882, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3883, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3884, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3885, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3886, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3887, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3888, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3889, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3890, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3891, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3892, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3893, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 3894, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3460, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3895, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3896, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3897, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3898, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3899, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3900, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3464, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3901, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3902, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3903, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3904, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36682, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36697, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36703, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36706, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36709, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36712, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53099, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53104, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53109, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53114, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53119, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53124, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53129, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53134, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53139, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53144, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53149, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53154, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53159, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53164, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 53169, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 53174, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 53182, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36805, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36808, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36811, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36817, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36820, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36823, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36826, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36829, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36832, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36835, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36838, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36841, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36844, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36847, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36850, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36883, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36886, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36889, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36892, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36895, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36898, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36901, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36904, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36907, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 36910, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4145, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4146, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4147, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 36916, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20535, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20539, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20541, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20543, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20545, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20547, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20549, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20551, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20553, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20555, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20557, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20559, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20561, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20563, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3809, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3817, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3818, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3821, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3823, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3824, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3826, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3827, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3828, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3829, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3830, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20565, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20567, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20569, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 20591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 53361, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 53367, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3460, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3895, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3896, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4222, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4223, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4224, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3471, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4225, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3483, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3545, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3544, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3491, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3531, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4226, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4227, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4228, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4229, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4230, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4231, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4232, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4233, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4234, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4235, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4236, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4237, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4238, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4239, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4240, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4241, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4242, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4243, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3897, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3898, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 3899, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4244, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4245, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4246, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4247, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4248, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4249, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4250, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4251, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4252, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4253, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20638, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20640, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20642, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20644, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20646, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20648, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20650, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20652, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20654, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20658, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20660, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20662, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20664, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, 20666, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20670, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20674, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20678, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20680, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20682, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 20684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37070, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37073, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37076, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 20695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 37081, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 20700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 37086, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4321, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4322, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4323, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4324, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4325, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4326, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4328, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4330, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4332, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4333, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4334, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4336, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4337, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4338, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4339, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4340, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4341, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4342, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4343, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4344, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4345, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4346, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4347, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4348, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4349, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4350, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4351, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4352, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4353, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4354, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4355, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4356, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4357, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4358, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4359, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4360, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4361, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4362, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4363, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4364, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4365, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4366, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 4367, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20752, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53522, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53527, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37153, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37161, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37164, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53551, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53557, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37178, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37181, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37184, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37197, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37200, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37205, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20834, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53610, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37239, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53632, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53638, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37259, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37262, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37265, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53652, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53657, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53663, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37284, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37287, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37290, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20909, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20911, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20913, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20915, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37301, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37304, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37313, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53705, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20946, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20948, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53718, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53724, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53729, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37351, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53738, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 20976, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37362, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37365, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37368, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37371, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37374, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53761, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37382, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21001, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37387, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37390, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37393, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53780, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37401, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37404, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37407, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21037, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21045, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53815, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53820, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37441, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37444, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37447, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53834, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21071, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37457, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53844, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21081, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53851, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37473, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21092, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21094, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21096, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21098, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21100, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21102, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21104, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21106, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21108, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21110, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37496, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37499, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37523, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37529, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37535, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37541, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21160, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21162, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37548, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21167, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21169, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 21171, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 37557, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 37560, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 21179, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21181, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21183, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21185, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21187, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53957, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21194, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21196, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21198, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21200, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21202, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21204, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21206, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21208, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 53981, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21218, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21220, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21222, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21224, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21226, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21228, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21230, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37616, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37622, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21244, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21246, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21248, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21250, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21252, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21254, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21256, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21258, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21260, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21262, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37648, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37651, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21270, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37662, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21281, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37667, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37670, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 54057, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21294, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37680, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37683, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 54076, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 54082, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21321, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21323, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21325, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21333, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21337, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21339, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21341, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21343, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21345, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21347, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21349, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21351, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21353, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21355, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 54125, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21362, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21364, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21366, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 54136, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37757, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21376, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21378, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21380, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21382, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21384, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21386, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21388, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21390, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21392, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21394, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37780, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21399, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21401, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37790, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21409, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 54179, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 37800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21419, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21421, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21423, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21425, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 37811, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 37814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21433, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21435, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21437, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21439, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21441, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21445, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21447, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 21449, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37835, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37838, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37841, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37844, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37847, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37850, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37883, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37886, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37889, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37892, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37895, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 37898, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, 37901, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5136, UINT16_MAX, 5136, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9615, UINT16_MAX, 9615, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5137, UINT16_MAX, 5137, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9616, UINT16_MAX, 9616, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5138, UINT16_MAX, 5138, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9617, UINT16_MAX, 9617, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5139, UINT16_MAX, 5139, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9618, UINT16_MAX, 9618, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5140, UINT16_MAX, 5140, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9619, UINT16_MAX, 9619, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1445, UINT16_MAX, 1445, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 8897, UINT16_MAX, 8897, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5141, UINT16_MAX, 5141, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9620, UINT16_MAX, 9620, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5142, UINT16_MAX, 5142, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9621, UINT16_MAX, 9621, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5143, UINT16_MAX, 5143, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9622, UINT16_MAX, 9622, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5144, UINT16_MAX, 5144, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9623, UINT16_MAX, 9623, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5145, UINT16_MAX, 5145, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9624, UINT16_MAX, 9624, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5146, UINT16_MAX, 5146, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9625, UINT16_MAX, 9625, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5147, UINT16_MAX, 5147, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9626, UINT16_MAX, 9626, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5148, UINT16_MAX, 5148, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9627, UINT16_MAX, 9627, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5149, UINT16_MAX, 5149, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9628, UINT16_MAX, 9628, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5150, UINT16_MAX, 5150, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9629, UINT16_MAX, 9629, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5151, UINT16_MAX, 5151, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9630, UINT16_MAX, 9630, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5152, UINT16_MAX, 5152, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9631, UINT16_MAX, 9631, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5153, UINT16_MAX, 5153, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9632, UINT16_MAX, 9632, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5154, UINT16_MAX, 5154, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9633, UINT16_MAX, 9633, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5155, UINT16_MAX, 5155, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9634, UINT16_MAX, 9634, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5156, UINT16_MAX, 5156, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9635, UINT16_MAX, 9635, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5157, UINT16_MAX, 5157, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9636, UINT16_MAX, 9636, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5158, UINT16_MAX, 5158, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9637, UINT16_MAX, 9637, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5159, UINT16_MAX, 5159, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9638, UINT16_MAX, 9638, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5160, UINT16_MAX, 5160, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9639, UINT16_MAX, 9639, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5161, UINT16_MAX, 5161, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9640, UINT16_MAX, 9640, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5162, UINT16_MAX, 5162, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9641, UINT16_MAX, 9641, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5163, UINT16_MAX, 5163, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9642, UINT16_MAX, 9642, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5164, UINT16_MAX, 5164, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9643, UINT16_MAX, 9643, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5165, UINT16_MAX, 5165, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9644, UINT16_MAX, 9644, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5166, UINT16_MAX, 5166, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9645, UINT16_MAX, 9645, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5167, UINT16_MAX, 5167, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9646, UINT16_MAX, 9646, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5168, UINT16_MAX, 5168, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9647, UINT16_MAX, 9647, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5169, UINT16_MAX, 5169, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9648, UINT16_MAX, 9648, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5170, UINT16_MAX, 5170, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9649, UINT16_MAX, 9649, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5171, UINT16_MAX, 5171, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9650, UINT16_MAX, 9650, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 981, UINT16_MAX, 9651, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 983, UINT16_MAX, 9652, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5172, UINT16_MAX, 5172, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9653, UINT16_MAX, 9653, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5173, UINT16_MAX, 5173, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9654, UINT16_MAX, 9654, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5174, UINT16_MAX, 5174, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9655, UINT16_MAX, 9655, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5175, UINT16_MAX, 5175, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9656, UINT16_MAX, 9656, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5176, UINT16_MAX, 5176, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9657, UINT16_MAX, 9657, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5177, UINT16_MAX, 5177, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9658, UINT16_MAX, 9658, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5178, UINT16_MAX, 5178, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9659, UINT16_MAX, 9659, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9660, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9661, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5179, UINT16_MAX, 5179, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9662, UINT16_MAX, 9662, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5180, UINT16_MAX, 5180, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9663, UINT16_MAX, 9663, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5181, UINT16_MAX, 5181, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9664, UINT16_MAX, 9664, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5182, UINT16_MAX, 5182, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9665, UINT16_MAX, 9665, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5183, UINT16_MAX, 5183, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9666, UINT16_MAX, 9666, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5184, UINT16_MAX, 5184, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9667, UINT16_MAX, 9667, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5185, UINT16_MAX, 5185, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9668, UINT16_MAX, 9668, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5186, UINT16_MAX, 5186, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9669, UINT16_MAX, 9669, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5187, UINT16_MAX, 5187, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9670, UINT16_MAX, 9670, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5188, UINT16_MAX, 5188, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9671, UINT16_MAX, 9671, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5189, UINT16_MAX, 5189, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9672, UINT16_MAX, 9672, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5190, UINT16_MAX, 5190, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9673, UINT16_MAX, 9673, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5191, UINT16_MAX, 5191, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9674, UINT16_MAX, 9674, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5192, UINT16_MAX, 5192, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9675, UINT16_MAX, 9675, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5193, UINT16_MAX, 5193, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9676, UINT16_MAX, 9676, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5194, UINT16_MAX, 5194, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9677, UINT16_MAX, 9677, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5195, UINT16_MAX, 5195, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9678, UINT16_MAX, 9678, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5196, UINT16_MAX, 5196, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9679, UINT16_MAX, 9679, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5197, UINT16_MAX, 5197, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9680, UINT16_MAX, 9680, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5198, UINT16_MAX, 5198, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9681, UINT16_MAX, 9681, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5199, UINT16_MAX, 5199, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9682, UINT16_MAX, 9682, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5200, UINT16_MAX, 5200, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9683, UINT16_MAX, 9683, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5201, UINT16_MAX, 5201, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9684, UINT16_MAX, 9684, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5202, UINT16_MAX, 5202, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9685, UINT16_MAX, 9685, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5203, UINT16_MAX, 5203, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9686, UINT16_MAX, 9686, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5204, UINT16_MAX, 5204, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9687, UINT16_MAX, 9687, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5205, UINT16_MAX, 5205, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9688, UINT16_MAX, 9688, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5206, UINT16_MAX, 5206, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9689, UINT16_MAX, 9689, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5207, UINT16_MAX, 5207, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9690, UINT16_MAX, 9690, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5208, UINT16_MAX, 5208, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9691, UINT16_MAX, 9691, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5209, UINT16_MAX, 5209, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9692, UINT16_MAX, 9692, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5209, UINT16_MAX, 9693, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9694, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9695, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9696, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9697, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9698, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9699, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9700, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9701, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5210, UINT16_MAX, 5210, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9702, UINT16_MAX, 9702, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5211, UINT16_MAX, 5211, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9703, UINT16_MAX, 9703, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5212, UINT16_MAX, 5212, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5213, UINT16_MAX, 5213, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9704, UINT16_MAX, 9704, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5214, UINT16_MAX, 5214, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9705, UINT16_MAX, 9705, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5215, UINT16_MAX, 5215, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9706, UINT16_MAX, 9706, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5216, UINT16_MAX, 5216, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9707, UINT16_MAX, 9707, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5217, UINT16_MAX, 5217, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9708, UINT16_MAX, 9708, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5218, UINT16_MAX, 5218, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9709, UINT16_MAX, 9709, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1524, UINT16_MAX, 1524, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7066, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5219, UINT16_MAX, 5219, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9710, UINT16_MAX, 9710, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5220, UINT16_MAX, 5220, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9711, UINT16_MAX, 9711, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9712, UINT16_MAX, 9712, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9713, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5221, UINT16_MAX, 5221, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9714, UINT16_MAX, 9714, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5222, UINT16_MAX, 5222, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9715, UINT16_MAX, 9715, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5223, UINT16_MAX, 5223, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9716, UINT16_MAX, 9716, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5224, UINT16_MAX, 5224, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9717, UINT16_MAX, 9717, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5225, UINT16_MAX, 5225, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9718, UINT16_MAX, 9718, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5226, UINT16_MAX, 5226, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9719, UINT16_MAX, 9719, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5227, UINT16_MAX, 5227, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9720, UINT16_MAX, 9720, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5228, UINT16_MAX, 5228, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9721, UINT16_MAX, 9721, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5229, UINT16_MAX, 5229, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9722, UINT16_MAX, 9722, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5230, UINT16_MAX, 5230, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9723, UINT16_MAX, 9723, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 785, UINT16_MAX, 785, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1515, UINT16_MAX, 1515, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1523, UINT16_MAX, 1523, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5231, UINT16_MAX, 5231, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1525, UINT16_MAX, 1525, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9724, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5232, UINT16_MAX, 5232, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5233, UINT16_MAX, 5233, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1527, UINT16_MAX, 1527, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5234, UINT16_MAX, 5234, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5235, UINT16_MAX, 5235, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9725, UINT16_MAX, 9725, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5236, UINT16_MAX, 5236, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9726, UINT16_MAX, 9726, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5237, UINT16_MAX, 5237, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9727, UINT16_MAX, 9727, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5238, UINT16_MAX, 5238, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9728, UINT16_MAX, 9728, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5239, UINT16_MAX, 5239, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9729, UINT16_MAX, 9729, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5240, UINT16_MAX, 5240, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9730, UINT16_MAX, 9730, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5241, UINT16_MAX, 5241, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9731, UINT16_MAX, 9731, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5242, UINT16_MAX, 5242, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9732, UINT16_MAX, 9732, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5243, UINT16_MAX, 5243, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 1536, UINT16_MAX, 1536, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5244, UINT16_MAX, 5244, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5245, UINT16_MAX, 5245, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9733, UINT16_MAX, 9733, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5246, UINT16_MAX, 5246, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9734, UINT16_MAX, 9734, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5247, UINT16_MAX, 5247, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9735, UINT16_MAX, 9735, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9736, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9737, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5248, UINT16_MAX, 5248, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9738, UINT16_MAX, 9738, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5249, UINT16_MAX, 5249, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9739, UINT16_MAX, 9739, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 2813, UINT16_MAX, 9740, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 2838, UINT16_MAX, 9741, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 2827, UINT16_MAX, 9742, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5250, UINT16_MAX, 5250, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9743, UINT16_MAX, 9743, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5251, UINT16_MAX, 9744, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 371, UINT16_MAX, 9745, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9746, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9747, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9748, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9749, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9750, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9751, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9752, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9753, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 5252, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9754, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9755, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9756, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9757, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9758, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9759, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9760, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9761, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9762, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9763, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9764, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9765, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9766, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9767, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9768, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9769, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9770, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9771, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9772, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9773, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9774, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9775, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9776, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9777, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9778, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9779, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 5253, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9780, UINT16_MAX, 9780, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9781, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9782, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9783, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9784, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9785, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9786, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9787, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5174, UINT16_MAX, 9788, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5252, UINT16_MAX, 9789, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3394, UINT16_MAX, 9790, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5253, UINT16_MAX, 9791, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9792, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9793, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9794, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9795, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9796, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9797, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7049, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7081, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9798, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5254, UINT16_MAX, 9799, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5255, 5255, UINT16_MAX, 5255, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5256, 5256, UINT16_MAX, 5256, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5257, 5257, UINT16_MAX, 5257, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5258, 5258, UINT16_MAX, 5258, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5259, 5259, UINT16_MAX, 5259, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5260, 5260, UINT16_MAX, 5260, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5261, 5261, UINT16_MAX, 5261, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5262, 5262, UINT16_MAX, 5262, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5263, 5263, UINT16_MAX, 5263, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5264, 5264, UINT16_MAX, 5264, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5265, 5265, UINT16_MAX, 5265, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5266, 5266, UINT16_MAX, 5266, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5267, 5267, UINT16_MAX, 5267, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5268, 5268, UINT16_MAX, 5268, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5269, 5269, UINT16_MAX, 5269, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5270, 5270, UINT16_MAX, 5270, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5271, 5271, UINT16_MAX, 5271, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5272, 5272, UINT16_MAX, 5272, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5273, 5273, UINT16_MAX, 5273, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5274, 5274, UINT16_MAX, 5274, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5275, 5275, UINT16_MAX, 5275, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5276, 5276, UINT16_MAX, 5276, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5277, 5277, UINT16_MAX, 5277, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5278, 5278, UINT16_MAX, 5278, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5279, 5279, UINT16_MAX, 5279, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5280, 5280, UINT16_MAX, 5280, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5281, 5281, UINT16_MAX, 5281, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5282, 5282, UINT16_MAX, 5282, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5283, 5283, UINT16_MAX, 5283, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5284, 5284, UINT16_MAX, 5284, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5285, 5285, UINT16_MAX, 5285, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5286, 5286, UINT16_MAX, 5286, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5287, 5287, UINT16_MAX, 5287, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5288, 5288, UINT16_MAX, 5288, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5289, 5289, UINT16_MAX, 5289, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5290, 5290, UINT16_MAX, 5290, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5291, 5291, UINT16_MAX, 5291, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5292, 5292, UINT16_MAX, 5292, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5293, 5293, UINT16_MAX, 5293, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5294, 5294, UINT16_MAX, 5294, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5295, 5295, UINT16_MAX, 5295, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5296, 5296, UINT16_MAX, 5296, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5297, 5297, UINT16_MAX, 5297, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5298, 5298, UINT16_MAX, 5298, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5299, 5299, UINT16_MAX, 5299, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5300, 5300, UINT16_MAX, 5300, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5301, 5301, UINT16_MAX, 5301, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5302, 5302, UINT16_MAX, 5302, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5303, 5303, UINT16_MAX, 5303, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5304, 5304, UINT16_MAX, 5304, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5305, 5305, UINT16_MAX, 5305, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5306, 5306, UINT16_MAX, 5306, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5307, 5307, UINT16_MAX, 5307, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5308, 5308, UINT16_MAX, 5308, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5309, 5309, UINT16_MAX, 5309, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5310, 5310, UINT16_MAX, 5310, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5311, 5311, UINT16_MAX, 5311, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5312, 5312, UINT16_MAX, 5312, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5313, 5313, UINT16_MAX, 5313, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5314, 5314, UINT16_MAX, 5314, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5315, 5315, UINT16_MAX, 5315, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5316, 5316, UINT16_MAX, 5316, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5317, 5317, UINT16_MAX, 5317, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5318, 5318, UINT16_MAX, 5318, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5319, 5319, UINT16_MAX, 5319, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5320, 5320, UINT16_MAX, 5320, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5321, 5321, UINT16_MAX, 5321, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5322, 5322, UINT16_MAX, 5322, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5323, 5323, UINT16_MAX, 5323, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5324, 5324, UINT16_MAX, 5324, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5325, 5325, UINT16_MAX, 5325, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5326, 5326, UINT16_MAX, 5326, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5327, 5327, UINT16_MAX, 5327, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5328, 5328, UINT16_MAX, 5328, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5329, 5329, UINT16_MAX, 5329, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5330, 5330, UINT16_MAX, 5330, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5331, 5331, UINT16_MAX, 5331, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5332, 5332, UINT16_MAX, 5332, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5333, 5333, UINT16_MAX, 5333, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 5334, 5334, UINT16_MAX, 5334, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_LV}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_LVT}, + {UTF8PROC_CATEGORY_CS, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_CO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5336, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5337, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5338, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5339, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5340, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5341, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5342, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5343, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5344, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5345, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5346, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5347, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5348, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5349, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5350, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5351, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5352, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5353, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5354, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5355, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5356, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5357, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5358, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5359, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5360, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5361, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5362, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5363, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5364, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5365, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5366, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5367, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5368, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5369, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5370, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5371, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5372, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5373, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5374, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5375, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5376, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5377, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5378, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5379, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5380, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5381, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5382, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5383, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5384, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5385, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5386, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5387, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5388, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5389, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5390, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5391, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5392, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5393, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3657, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5394, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5395, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5396, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5397, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5398, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5399, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5400, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5401, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5402, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5403, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5404, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5405, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5406, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5407, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5408, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5409, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5410, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5411, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5412, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5413, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5414, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5415, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5416, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5417, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5418, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5419, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5420, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5421, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5422, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5423, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5424, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5425, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5426, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5427, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5428, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5429, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5430, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5431, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5432, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5433, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5434, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5435, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5436, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5437, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5438, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5439, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5440, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3620, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5441, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5442, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5443, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5444, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5445, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5446, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5447, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5448, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5449, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5450, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5451, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5452, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5453, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5454, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5455, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5456, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5457, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5458, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5459, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5460, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5461, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5462, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5463, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3478, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5464, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5465, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5467, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5469, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5470, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5471, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5472, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5473, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5474, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5475, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5476, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5477, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5478, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5479, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5480, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5481, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5482, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5483, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5484, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5485, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5486, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5487, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5488, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5489, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5490, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5491, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5492, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5493, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5494, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5495, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5496, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5497, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5498, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5499, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5500, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5501, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5503, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5505, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5507, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5509, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5511, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5512, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5513, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5515, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5517, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3671, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5519, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5521, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5522, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5523, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5524, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5525, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5527, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5528, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5529, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 4223, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5531, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5535, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5539, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5541, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5542, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5543, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5544, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5545, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5546, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5547, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5548, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5549, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5550, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5551, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5552, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5553, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5554, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5555, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5556, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5557, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5559, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5560, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5561, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5562, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5563, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5564, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5565, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5566, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5567, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5568, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5569, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5570, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5572, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5574, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5576, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5578, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5580, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3606, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5582, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5584, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5586, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5588, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5590, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5592, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5594, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5596, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5598, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5606, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5607, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5608, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5610, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5612, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5614, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5616, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5620, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5622, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5624, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5627, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5628, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5630, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5631, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5632, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 4228, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5633, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5634, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5636, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 4232, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5637, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5638, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5639, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5640, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5641, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5642, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5643, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5644, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5645, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5646, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5647, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5648, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5649, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5650, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5651, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5652, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5653, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5654, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5655, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5656, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5657, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5658, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5660, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5662, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5663, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5664, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5665, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5666, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5667, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5669, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5670, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5671, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5674, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5677, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5678, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5680, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5681, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5682, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5683, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5692, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3537, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5697, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5698, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5699, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5701, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5702, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5703, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5704, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5705, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5706, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5707, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5708, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5709, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5710, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5711, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5712, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5713, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5714, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5715, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5716, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5717, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5718, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5719, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5720, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5721, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5723, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5724, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5725, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5726, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5727, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5728, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5729, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5730, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5731, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5733, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5735, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5737, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5738, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5739, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5740, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5742, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5744, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5746, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 5747, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22132, 22132, 9800, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22134, 22134, 9801, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22136, 22136, 9802, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 38522, 38522, 9803, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 38525, 38525, 9804, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22144, 22146, 9805, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22146, 22146, 9806, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22148, 22148, 9807, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22150, 22150, 9808, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22152, 22152, 9809, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22154, 22154, 9810, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 22156, 22156, 9811, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22158, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 26, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22160, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5778, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 2840, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 2843, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5779, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5780, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5781, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5782, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5783, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, 5784, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_FONT, 2800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22169, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22171, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22173, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22175, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22177, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22179, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22181, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22183, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22185, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22187, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22189, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22191, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22193, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22195, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22197, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22199, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22201, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22203, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22205, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22207, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22209, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22211, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22213, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22215, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22217, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22219, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22221, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22223, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22225, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22227, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22229, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, 22231, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_COMPAT, 22233, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5851, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5851, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5854, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5854, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5854, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5854, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5855, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5855, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5855, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5855, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5856, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5857, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5857, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5857, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5857, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5860, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5860, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5860, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5860, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5861, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5861, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5861, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5861, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5863, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5863, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5863, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5863, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5864, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5864, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5866, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5866, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5867, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5867, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5869, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5869, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5872, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5872, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5872, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5872, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5873, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5873, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5873, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5873, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5875, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5875, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5875, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5875, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5876, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5876, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5879, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5879, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5881, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5881, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5881, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5881, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5882, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5882, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5883, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5883, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5884, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5884, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5885, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5886, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5886, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5887, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5887, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5888, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5888, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5889, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5889, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5889, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5889, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5890, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5890, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22275, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22275, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22277, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22277, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22279, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22279, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22281, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22281, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22283, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22283, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22285, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22285, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22287, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22287, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22287, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22289, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22289, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22289, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5907, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5907, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 5907, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 5907, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22292, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22294, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22296, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22298, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22300, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22302, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22304, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22306, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22308, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22310, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22312, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22314, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22316, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22318, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22320, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22322, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22324, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22326, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22328, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22330, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22332, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22334, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22336, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22338, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22340, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22342, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22344, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22346, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22348, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22350, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22352, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22354, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22356, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22358, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22360, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22362, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22364, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22366, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22368, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22370, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22372, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22374, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22376, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22378, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22380, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22382, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22384, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22386, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22388, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22390, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22392, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22394, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22396, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22398, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22400, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22402, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22404, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22406, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22408, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22410, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22412, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22414, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22416, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22418, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22420, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22422, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22424, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22426, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22428, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22430, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22432, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22434, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22436, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22438, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22440, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22442, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22444, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22446, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22448, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22450, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22452, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22454, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22456, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22458, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22460, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22462, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22464, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22470, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22472, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22474, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22476, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 38862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 38865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 38868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 38871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 38874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 38877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22496, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22498, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22296, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22500, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22298, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22504, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22306, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22506, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22308, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22310, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22510, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22318, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22512, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22320, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22322, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22516, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22326, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22518, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22328, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22330, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22388, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22390, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22396, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22398, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22400, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22408, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22410, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22412, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22414, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22422, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22424, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22426, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22520, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22434, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22522, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22524, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22446, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22526, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22448, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22450, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22476, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22528, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22530, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22532, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22470, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22292, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22294, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22534, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22296, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22300, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22302, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22304, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22306, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22312, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22314, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22316, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22318, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22326, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22332, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22334, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22336, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22338, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22340, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22344, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22346, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22348, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22350, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22352, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22354, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22542, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22356, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22358, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22360, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22362, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22364, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22366, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22370, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22372, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22374, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22376, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22378, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22380, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22382, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22384, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22386, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22392, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22394, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22402, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22404, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22406, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22408, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22410, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22416, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22418, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22420, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22422, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22544, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22428, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22430, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22432, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22434, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22440, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22442, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22444, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22446, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22546, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22452, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22454, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22548, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22460, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22462, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22464, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22550, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22296, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22536, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22306, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22538, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22318, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22540, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22326, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22552, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22352, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22554, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22556, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22408, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22410, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22422, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22446, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22546, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22550, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 38944, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 38947, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 38950, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22569, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22607, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22556, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22569, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22571, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22573, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22575, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22577, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22579, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22583, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22587, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22591, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22595, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22599, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22607, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22556, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22556, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22554, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22558, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 22368, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22346, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22348, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22350, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22368, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 22370, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 22623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 22623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39009, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39012, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39012, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39015, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39018, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39021, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39024, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39027, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39030, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39030, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39033, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39036, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39039, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39042, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39045, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39048, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39048, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39051, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39054, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39054, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39057, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39057, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39060, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39063, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39063, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39066, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39069, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39069, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39072, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39072, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39075, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39078, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39078, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39081, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39081, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39084, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39087, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39090, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39093, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39093, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39096, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39099, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39102, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39105, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39108, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39108, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39111, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39114, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39117, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39120, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39123, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39126, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39126, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39129, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39129, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39132, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39132, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39135, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39138, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39141, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39144, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39147, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39150, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39153, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39156, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39159, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39162, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39165, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39168, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39171, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39171, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39174, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39177, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39180, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39183, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39183, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39186, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39189, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39192, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39195, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39198, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39201, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39204, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39207, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39210, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39213, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39216, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39219, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39222, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39225, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39228, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39231, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39234, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39237, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39240, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39243, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39246, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39249, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39111, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39117, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39252, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39255, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39258, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39261, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39264, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39267, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39264, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39258, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39270, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39273, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39276, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39279, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39282, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39267, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39090, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 39060, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39285, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 39288, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 39291, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 39294, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 55681, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 55686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 55691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 55696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 55701, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 55706, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 55711, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 39332, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 55719, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 55738, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 55747, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6606, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6607, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6608, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6610, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6612, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 2803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 2804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6614, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6616, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6618, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6619, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6620, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 3067, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 3068, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6622, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6623, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6624, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, 6626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 6627, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, 6612, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, 6600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, 2762, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, 6603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6610, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 2803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 2804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6614, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6616, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, 6628, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6630, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SMALL, 2800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SMALL, 6631, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6632, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6633, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 2802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6634, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, 6635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, 6636, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, 6637, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23022, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 23024, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23026, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23028, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23030, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 23032, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23034, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 23036, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23038, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 23040, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23042, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 23044, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23046, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 23048, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6666, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6667, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6667, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6669, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6669, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6670, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6670, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6671, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6671, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6671, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6671, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6674, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6674, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6677, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6677, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6677, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6677, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6678, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6678, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6678, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6678, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6680, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6680, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6681, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6681, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6682, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6682, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6683, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6683, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6692, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6692, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6692, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6692, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6697, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6697, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6697, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6697, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6698, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6698, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6698, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6698, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6699, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6699, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 5890, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 5890, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 6700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 6700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, 6700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, 6700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23085, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 23085, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23087, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 23087, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23089, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 23089, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, 23091, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, 23091, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6709, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6628, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6635, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6636, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6629, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6710, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 2803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 2804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6630, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_WIDE, 2800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, 6600, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_WIDE, 6631, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, 2762, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, 6711, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 38, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 31, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 32, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, 2799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, 6603, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6632, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 2802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6633, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6637, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1491, 6712, UINT16_MAX, 6712, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1493, 6713, UINT16_MAX, 6713, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2813, 6714, UINT16_MAX, 6714, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1494, 6715, UINT16_MAX, 6715, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1495, 6716, UINT16_MAX, 6716, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2838, 6717, UINT16_MAX, 6717, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1497, 6718, UINT16_MAX, 6718, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1498, 6719, UINT16_MAX, 6719, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1499, 6720, UINT16_MAX, 6720, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1500, 6721, UINT16_MAX, 6721, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1501, 6722, UINT16_MAX, 6722, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1502, 6723, UINT16_MAX, 6723, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1503, 6724, UINT16_MAX, 6724, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1504, 6725, UINT16_MAX, 6725, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1505, 6726, UINT16_MAX, 6726, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1507, 6727, UINT16_MAX, 6727, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2827, 6728, UINT16_MAX, 6728, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1508, 6729, UINT16_MAX, 6729, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 3320, 6730, UINT16_MAX, 6730, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1509, 6731, UINT16_MAX, 6731, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1510, 6732, UINT16_MAX, 6732, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2910, 6733, UINT16_MAX, 6733, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1511, 6734, UINT16_MAX, 6734, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2928, 6735, UINT16_MAX, 6735, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 3327, 6736, UINT16_MAX, 6736, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2835, 6737, UINT16_MAX, 6737, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6634, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6626, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6738, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6612, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 2722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 0, UINT16_MAX, 9812, UINT16_MAX, 9812, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 1, UINT16_MAX, 9813, UINT16_MAX, 9813, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 2, UINT16_MAX, 9814, UINT16_MAX, 9814, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 3, UINT16_MAX, 9815, UINT16_MAX, 9815, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 4, UINT16_MAX, 9816, UINT16_MAX, 9816, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 5, UINT16_MAX, 9817, UINT16_MAX, 9817, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 6, UINT16_MAX, 9818, UINT16_MAX, 9818, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 7, UINT16_MAX, 9819, UINT16_MAX, 9819, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 8, UINT16_MAX, 9820, UINT16_MAX, 9820, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 9, UINT16_MAX, 9821, UINT16_MAX, 9821, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 10, UINT16_MAX, 9822, UINT16_MAX, 9822, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 11, UINT16_MAX, 9823, UINT16_MAX, 9823, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 12, UINT16_MAX, 9824, UINT16_MAX, 9824, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 13, UINT16_MAX, 9825, UINT16_MAX, 9825, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 14, UINT16_MAX, 9826, UINT16_MAX, 9826, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 15, UINT16_MAX, 9827, UINT16_MAX, 9827, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 16, UINT16_MAX, 9828, UINT16_MAX, 9828, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 17, UINT16_MAX, 9829, UINT16_MAX, 9829, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 18, UINT16_MAX, 9830, UINT16_MAX, 9830, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 19, UINT16_MAX, 9831, UINT16_MAX, 9831, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 20, UINT16_MAX, 9832, UINT16_MAX, 9832, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 21, UINT16_MAX, 9833, UINT16_MAX, 9833, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 22, UINT16_MAX, 9834, UINT16_MAX, 9834, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 23, UINT16_MAX, 9835, UINT16_MAX, 9835, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 24, UINT16_MAX, 9836, UINT16_MAX, 9836, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, 25, UINT16_MAX, 9837, UINT16_MAX, 9837, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6739, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6614, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6740, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6741, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6742, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6602, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6622, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6743, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4367, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6744, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6745, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6746, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6747, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6748, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6749, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6750, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6751, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6752, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6753, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4321, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4322, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4323, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4324, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4325, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4326, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4327, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4328, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4330, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4332, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4333, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4334, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4336, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4337, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4338, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4339, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4340, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4341, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4342, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4343, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4344, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4345, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4346, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4347, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4348, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4349, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4350, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4351, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4352, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4353, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4354, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4355, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4356, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4357, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4358, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4359, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4360, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4361, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4362, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4363, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 4364, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6754, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6755, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6756, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6757, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, true, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6758, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6759, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6760, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6761, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6762, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6763, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6764, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6765, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6766, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6767, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6768, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6769, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6770, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6771, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6772, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6773, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6774, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6775, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6776, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6777, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6778, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6779, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6780, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6781, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6782, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6783, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6784, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6788, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6789, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6790, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6791, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6805, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6806, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6807, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, 6808, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6809, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6810, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6811, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6812, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, 6813, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, 6815, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6816, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6817, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6818, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6820, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6821, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, 6822, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6823, UINT16_MAX, 6823, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6825, UINT16_MAX, 6825, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6827, UINT16_MAX, 6827, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6829, UINT16_MAX, 6829, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6831, UINT16_MAX, 6831, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6833, UINT16_MAX, 6833, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6835, UINT16_MAX, 6835, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6837, UINT16_MAX, 6837, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6839, UINT16_MAX, 6839, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6841, UINT16_MAX, 6841, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6843, UINT16_MAX, 6843, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6845, UINT16_MAX, 6845, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6847, UINT16_MAX, 6847, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6849, UINT16_MAX, 6849, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6851, UINT16_MAX, 6851, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6853, UINT16_MAX, 6853, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6855, UINT16_MAX, 6855, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6857, UINT16_MAX, 6857, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6859, UINT16_MAX, 6859, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6861, UINT16_MAX, 6861, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6863, UINT16_MAX, 6863, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6865, UINT16_MAX, 6865, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6867, UINT16_MAX, 6867, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6869, UINT16_MAX, 6869, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6871, UINT16_MAX, 6871, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6873, UINT16_MAX, 6873, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6875, UINT16_MAX, 6875, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6877, UINT16_MAX, 6877, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6879, UINT16_MAX, 6879, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6881, UINT16_MAX, 6881, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6883, UINT16_MAX, 6883, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6885, UINT16_MAX, 6885, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6887, UINT16_MAX, 6887, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6889, UINT16_MAX, 6889, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6891, UINT16_MAX, 6891, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6893, UINT16_MAX, 6893, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6895, UINT16_MAX, 6895, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6897, UINT16_MAX, 6897, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6899, UINT16_MAX, 6899, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6901, UINT16_MAX, 6901, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9838, UINT16_MAX, 9838, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9840, UINT16_MAX, 9840, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9842, UINT16_MAX, 9842, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9844, UINT16_MAX, 9844, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9846, UINT16_MAX, 9846, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9848, UINT16_MAX, 9848, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9850, UINT16_MAX, 9850, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9852, UINT16_MAX, 9852, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9854, UINT16_MAX, 9854, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9856, UINT16_MAX, 9856, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9858, UINT16_MAX, 9858, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9860, UINT16_MAX, 9860, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9862, UINT16_MAX, 9862, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9864, UINT16_MAX, 9864, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9866, UINT16_MAX, 9866, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9868, UINT16_MAX, 9868, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9870, UINT16_MAX, 9870, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9872, UINT16_MAX, 9872, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9874, UINT16_MAX, 9874, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9876, UINT16_MAX, 9876, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9878, UINT16_MAX, 9878, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9880, UINT16_MAX, 9880, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9882, UINT16_MAX, 9882, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9884, UINT16_MAX, 9884, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9886, UINT16_MAX, 9886, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9888, UINT16_MAX, 9888, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9890, UINT16_MAX, 9890, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9892, UINT16_MAX, 9892, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9894, UINT16_MAX, 9894, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9896, UINT16_MAX, 9896, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9898, UINT16_MAX, 9898, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9900, UINT16_MAX, 9900, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9902, UINT16_MAX, 9902, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9904, UINT16_MAX, 9904, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9906, UINT16_MAX, 9906, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9908, UINT16_MAX, 9908, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9910, UINT16_MAX, 9910, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9912, UINT16_MAX, 9912, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9914, UINT16_MAX, 9914, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9916, UINT16_MAX, 9916, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6903, UINT16_MAX, 6903, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6905, UINT16_MAX, 6905, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6907, UINT16_MAX, 6907, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6909, UINT16_MAX, 6909, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6911, UINT16_MAX, 6911, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6913, UINT16_MAX, 6913, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6915, UINT16_MAX, 6915, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6917, UINT16_MAX, 6917, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6919, UINT16_MAX, 6919, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6921, UINT16_MAX, 6921, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6923, UINT16_MAX, 6923, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6925, UINT16_MAX, 6925, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6927, UINT16_MAX, 6927, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6929, UINT16_MAX, 6929, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6931, UINT16_MAX, 6931, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6933, UINT16_MAX, 6933, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6935, UINT16_MAX, 6935, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6937, UINT16_MAX, 6937, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6939, UINT16_MAX, 6939, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6941, UINT16_MAX, 6941, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6943, UINT16_MAX, 6943, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6945, UINT16_MAX, 6945, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6947, UINT16_MAX, 6947, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6949, UINT16_MAX, 6949, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6951, UINT16_MAX, 6951, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6953, UINT16_MAX, 6953, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6955, UINT16_MAX, 6955, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6957, UINT16_MAX, 6957, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6959, UINT16_MAX, 6959, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6961, UINT16_MAX, 6961, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6963, UINT16_MAX, 6963, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6965, UINT16_MAX, 6965, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6967, UINT16_MAX, 6967, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6969, UINT16_MAX, 6969, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6971, UINT16_MAX, 6971, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6973, UINT16_MAX, 6973, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9918, UINT16_MAX, 9918, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9920, UINT16_MAX, 9920, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9922, UINT16_MAX, 9922, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9924, UINT16_MAX, 9924, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9926, UINT16_MAX, 9926, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9928, UINT16_MAX, 9928, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9930, UINT16_MAX, 9930, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9932, UINT16_MAX, 9932, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9934, UINT16_MAX, 9934, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9936, UINT16_MAX, 9936, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9938, UINT16_MAX, 9938, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9940, UINT16_MAX, 9940, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9942, UINT16_MAX, 9942, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9944, UINT16_MAX, 9944, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9946, UINT16_MAX, 9946, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9948, UINT16_MAX, 9948, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9950, UINT16_MAX, 9950, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9952, UINT16_MAX, 9952, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9954, UINT16_MAX, 9954, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9956, UINT16_MAX, 9956, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9958, UINT16_MAX, 9958, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9960, UINT16_MAX, 9960, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9962, UINT16_MAX, 9962, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9964, UINT16_MAX, 9964, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9966, UINT16_MAX, 9966, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9968, UINT16_MAX, 9968, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9970, UINT16_MAX, 9970, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9972, UINT16_MAX, 9972, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9974, UINT16_MAX, 9974, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9976, UINT16_MAX, 9976, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9978, UINT16_MAX, 9978, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9980, UINT16_MAX, 9980, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9982, UINT16_MAX, 9982, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9984, UINT16_MAX, 9984, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9986, UINT16_MAX, 9986, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9988, UINT16_MAX, 9988, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6975, UINT16_MAX, 6975, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6977, UINT16_MAX, 6977, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6979, UINT16_MAX, 6979, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6981, UINT16_MAX, 6981, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6983, UINT16_MAX, 6983, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6985, UINT16_MAX, 6985, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6987, UINT16_MAX, 6987, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6989, UINT16_MAX, 6989, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6991, UINT16_MAX, 6991, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6993, UINT16_MAX, 6993, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6995, UINT16_MAX, 6995, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6997, UINT16_MAX, 6997, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 6999, UINT16_MAX, 6999, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7001, UINT16_MAX, 7001, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7003, UINT16_MAX, 7003, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7005, UINT16_MAX, 7005, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7007, UINT16_MAX, 7007, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7009, UINT16_MAX, 7009, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7011, UINT16_MAX, 7011, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7013, UINT16_MAX, 7013, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7015, UINT16_MAX, 7015, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7017, UINT16_MAX, 7017, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7019, UINT16_MAX, 7019, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7021, UINT16_MAX, 7021, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7023, UINT16_MAX, 7023, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7025, UINT16_MAX, 7025, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7027, UINT16_MAX, 7027, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7029, UINT16_MAX, 7029, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7031, UINT16_MAX, 7031, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7033, UINT16_MAX, 7033, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7035, UINT16_MAX, 7035, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7037, UINT16_MAX, 7037, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7039, UINT16_MAX, 7039, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7041, UINT16_MAX, 7041, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7043, UINT16_MAX, 7043, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9990, UINT16_MAX, 9990, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9992, UINT16_MAX, 9992, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9994, UINT16_MAX, 9994, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9996, UINT16_MAX, 9996, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 9998, UINT16_MAX, 9998, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10000, UINT16_MAX, 10000, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10002, UINT16_MAX, 10002, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10004, UINT16_MAX, 10004, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10006, UINT16_MAX, 10006, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10008, UINT16_MAX, 10008, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10010, UINT16_MAX, 10010, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10012, UINT16_MAX, 10012, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10014, UINT16_MAX, 10014, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10016, UINT16_MAX, 10016, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10018, UINT16_MAX, 10018, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10020, UINT16_MAX, 10020, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10022, UINT16_MAX, 10022, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10024, UINT16_MAX, 10024, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10026, UINT16_MAX, 10026, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10028, UINT16_MAX, 10028, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10030, UINT16_MAX, 10030, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10032, UINT16_MAX, 10032, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10034, UINT16_MAX, 10034, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10036, UINT16_MAX, 10036, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10038, UINT16_MAX, 10038, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10040, UINT16_MAX, 10040, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10042, UINT16_MAX, 10042, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10044, UINT16_MAX, 10044, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10046, UINT16_MAX, 10046, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10048, UINT16_MAX, 10048, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10050, UINT16_MAX, 10050, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10052, UINT16_MAX, 10052, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10054, UINT16_MAX, 10054, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10056, UINT16_MAX, 10056, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10058, UINT16_MAX, 10058, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10060, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7045, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7046, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 66, UINT16_MAX, 10062, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7047, UINT16_MAX, 10064, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 476, UINT16_MAX, 10066, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7048, UINT16_MAX, 10068, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7049, UINT16_MAX, 10070, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7050, UINT16_MAX, 10072, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7051, UINT16_MAX, 10074, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 481, UINT16_MAX, 10076, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 482, UINT16_MAX, 10078, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7052, UINT16_MAX, 10080, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7053, UINT16_MAX, 10082, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7054, UINT16_MAX, 10084, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7055, UINT16_MAX, 10086, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7056, UINT16_MAX, 10088, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7057, UINT16_MAX, 10090, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 488, UINT16_MAX, 10092, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7058, UINT16_MAX, 10094, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 277, UINT16_MAX, 10096, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7059, UINT16_MAX, 10098, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7060, UINT16_MAX, 10100, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7061, UINT16_MAX, 10102, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7062, UINT16_MAX, 10104, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7063, UINT16_MAX, 10106, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5231, UINT16_MAX, 10108, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7064, UINT16_MAX, 10110, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7066, UINT16_MAX, 10112, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7067, UINT16_MAX, 10114, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7068, UINT16_MAX, 10116, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7070, UINT16_MAX, 10118, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7071, UINT16_MAX, 10120, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 113, UINT16_MAX, 10122, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7073, UINT16_MAX, 10124, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7074, UINT16_MAX, 10126, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 16, UINT16_MAX, 10128, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7075, UINT16_MAX, 10130, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7076, UINT16_MAX, 10132, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 3396, UINT16_MAX, 10134, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7078, UINT16_MAX, 10136, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 503, UINT16_MAX, 10138, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7079, UINT16_MAX, 10140, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7080, UINT16_MAX, 10142, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7081, UINT16_MAX, 10144, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7082, UINT16_MAX, 10146, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 507, UINT16_MAX, 10148, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7083, UINT16_MAX, 10150, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7084, UINT16_MAX, 10152, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7085, UINT16_MAX, 10154, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7086, UINT16_MAX, 10156, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7087, UINT16_MAX, 10158, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7088, UINT16_MAX, 10160, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7089, UINT16_MAX, 10162, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7090, UINT16_MAX, 10164, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7091, UINT16_MAX, 10166, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 7093, UINT16_MAX, 10168, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7095, UINT16_MAX, 7095, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7097, UINT16_MAX, 7097, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7099, UINT16_MAX, 7099, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7101, UINT16_MAX, 7101, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7103, UINT16_MAX, 7103, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7105, UINT16_MAX, 7105, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7107, UINT16_MAX, 7107, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7109, UINT16_MAX, 7109, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7111, UINT16_MAX, 7111, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7113, UINT16_MAX, 7113, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7115, UINT16_MAX, 7115, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7117, UINT16_MAX, 7117, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7119, UINT16_MAX, 7119, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7121, UINT16_MAX, 7121, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7123, UINT16_MAX, 7123, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7125, UINT16_MAX, 7125, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7127, UINT16_MAX, 7127, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7129, UINT16_MAX, 7129, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7131, UINT16_MAX, 7131, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7133, UINT16_MAX, 7133, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7135, UINT16_MAX, 7135, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7137, UINT16_MAX, 7137, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7139, UINT16_MAX, 7139, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7141, UINT16_MAX, 7141, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7143, UINT16_MAX, 7143, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7145, UINT16_MAX, 7145, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7147, UINT16_MAX, 7147, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7149, UINT16_MAX, 7149, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7151, UINT16_MAX, 7151, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7153, UINT16_MAX, 7153, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7155, UINT16_MAX, 7155, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7157, UINT16_MAX, 7157, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7159, UINT16_MAX, 7159, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7161, UINT16_MAX, 7161, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7163, UINT16_MAX, 7163, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7165, UINT16_MAX, 7165, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7167, UINT16_MAX, 7167, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7169, UINT16_MAX, 7169, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7171, UINT16_MAX, 7171, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7173, UINT16_MAX, 7173, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7175, UINT16_MAX, 7175, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7177, UINT16_MAX, 7177, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7179, UINT16_MAX, 7179, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7181, UINT16_MAX, 7181, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7183, UINT16_MAX, 7183, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7185, UINT16_MAX, 7185, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7187, UINT16_MAX, 7187, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7189, UINT16_MAX, 7189, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7191, UINT16_MAX, 7191, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7193, UINT16_MAX, 7193, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7195, UINT16_MAX, 7195, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10170, UINT16_MAX, 10170, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10172, UINT16_MAX, 10172, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10174, UINT16_MAX, 10174, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10176, UINT16_MAX, 10176, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10178, UINT16_MAX, 10178, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10180, UINT16_MAX, 10180, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10182, UINT16_MAX, 10182, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10184, UINT16_MAX, 10184, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10186, UINT16_MAX, 10186, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10188, UINT16_MAX, 10188, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10190, UINT16_MAX, 10190, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10192, UINT16_MAX, 10192, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10194, UINT16_MAX, 10194, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10196, UINT16_MAX, 10196, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10198, UINT16_MAX, 10198, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10200, UINT16_MAX, 10200, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10202, UINT16_MAX, 10202, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10204, UINT16_MAX, 10204, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10206, UINT16_MAX, 10206, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10208, UINT16_MAX, 10208, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10210, UINT16_MAX, 10210, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10212, UINT16_MAX, 10212, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10214, UINT16_MAX, 10214, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10216, UINT16_MAX, 10216, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10218, UINT16_MAX, 10218, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10220, UINT16_MAX, 10220, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10222, UINT16_MAX, 10222, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10224, UINT16_MAX, 10224, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10226, UINT16_MAX, 10226, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10228, UINT16_MAX, 10228, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10230, UINT16_MAX, 10230, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10232, UINT16_MAX, 10232, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10234, UINT16_MAX, 10234, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10236, UINT16_MAX, 10236, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10238, UINT16_MAX, 10238, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10240, UINT16_MAX, 10240, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10242, UINT16_MAX, 10242, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10244, UINT16_MAX, 10244, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10246, UINT16_MAX, 10246, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10248, UINT16_MAX, 10248, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10250, UINT16_MAX, 10250, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10252, UINT16_MAX, 10252, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10254, UINT16_MAX, 10254, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10256, UINT16_MAX, 10256, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10258, UINT16_MAX, 10258, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10260, UINT16_MAX, 10260, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10262, UINT16_MAX, 10262, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10264, UINT16_MAX, 10264, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10266, UINT16_MAX, 10266, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10268, UINT16_MAX, 10268, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 10270, UINT16_MAX, 10270, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_AN, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_AL, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5328, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23581, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5332, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23585, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5336, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23589, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MN, 7, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49206, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_PREPEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49208, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 23593, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, 23597, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5340, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5344, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49210, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5348, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 23601, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 23605, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49212, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49216, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5354, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49214, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 23609, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 23613, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49218, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 23617, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49220, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5362, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5366, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 23621, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 23625, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7245, UINT16_MAX, 7245, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7247, UINT16_MAX, 7247, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7249, UINT16_MAX, 7249, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7251, UINT16_MAX, 7251, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7253, UINT16_MAX, 7253, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7255, UINT16_MAX, 7255, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7257, UINT16_MAX, 7257, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7259, UINT16_MAX, 7259, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7261, UINT16_MAX, 7261, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7263, UINT16_MAX, 7263, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7265, UINT16_MAX, 7265, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7267, UINT16_MAX, 7267, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7269, UINT16_MAX, 7269, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7271, UINT16_MAX, 7271, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7273, UINT16_MAX, 7273, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7275, UINT16_MAX, 7275, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7277, UINT16_MAX, 7277, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7279, UINT16_MAX, 7279, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7281, UINT16_MAX, 7281, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7283, UINT16_MAX, 7283, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7285, UINT16_MAX, 7285, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7287, UINT16_MAX, 7287, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7289, UINT16_MAX, 7289, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7291, UINT16_MAX, 7291, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7293, UINT16_MAX, 7293, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7295, UINT16_MAX, 7295, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7297, UINT16_MAX, 7297, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7299, UINT16_MAX, 7299, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7301, UINT16_MAX, 7301, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7303, UINT16_MAX, 7303, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7305, UINT16_MAX, 7305, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7307, UINT16_MAX, 7307, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10272, UINT16_MAX, 10272, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10274, UINT16_MAX, 10274, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10276, UINT16_MAX, 10276, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10278, UINT16_MAX, 10278, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10280, UINT16_MAX, 10280, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10282, UINT16_MAX, 10282, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10284, UINT16_MAX, 10284, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10286, UINT16_MAX, 10286, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10288, UINT16_MAX, 10288, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10290, UINT16_MAX, 10290, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10292, UINT16_MAX, 10292, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10294, UINT16_MAX, 10294, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10296, UINT16_MAX, 10296, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10298, UINT16_MAX, 10298, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10300, UINT16_MAX, 10300, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10302, UINT16_MAX, 10302, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10304, UINT16_MAX, 10304, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10306, UINT16_MAX, 10306, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10308, UINT16_MAX, 10308, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10310, UINT16_MAX, 10310, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10312, UINT16_MAX, 10312, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10314, UINT16_MAX, 10314, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10316, UINT16_MAX, 10316, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10318, UINT16_MAX, 10318, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10320, UINT16_MAX, 10320, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10322, UINT16_MAX, 10322, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10324, UINT16_MAX, 10324, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10326, UINT16_MAX, 10326, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10328, UINT16_MAX, 10328, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10330, UINT16_MAX, 10330, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10332, UINT16_MAX, 10332, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10334, UINT16_MAX, 10334, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49222, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5370, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, 23693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MN, 9, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, true, 0, 0, UTF8PROC_BOUNDCLASS_CONTROL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7313, UINT16_MAX, 7313, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7315, UINT16_MAX, 7315, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7317, UINT16_MAX, 7317, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7319, UINT16_MAX, 7319, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7321, UINT16_MAX, 7321, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7323, UINT16_MAX, 7323, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7325, UINT16_MAX, 7325, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7327, UINT16_MAX, 7327, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7329, UINT16_MAX, 7329, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7331, UINT16_MAX, 7331, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7333, UINT16_MAX, 7333, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7335, UINT16_MAX, 7335, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7337, UINT16_MAX, 7337, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7339, UINT16_MAX, 7339, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7341, UINT16_MAX, 7341, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7343, UINT16_MAX, 7343, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7345, UINT16_MAX, 7345, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7347, UINT16_MAX, 7347, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7349, UINT16_MAX, 7349, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7351, UINT16_MAX, 7351, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7353, UINT16_MAX, 7353, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7355, UINT16_MAX, 7355, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7357, UINT16_MAX, 7357, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7359, UINT16_MAX, 7359, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7361, UINT16_MAX, 7361, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7363, UINT16_MAX, 7363, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7365, UINT16_MAX, 7365, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7367, UINT16_MAX, 7367, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7369, UINT16_MAX, 7369, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7371, UINT16_MAX, 7371, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7373, UINT16_MAX, 7373, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, 7375, UINT16_MAX, 7375, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10336, UINT16_MAX, 10336, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10338, UINT16_MAX, 10338, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10340, UINT16_MAX, 10340, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10342, UINT16_MAX, 10342, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10344, UINT16_MAX, 10344, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10346, UINT16_MAX, 10346, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10348, UINT16_MAX, 10348, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10350, UINT16_MAX, 10350, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10352, UINT16_MAX, 10352, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10354, UINT16_MAX, 10354, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10356, UINT16_MAX, 10356, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10358, UINT16_MAX, 10358, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10360, UINT16_MAX, 10360, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10362, UINT16_MAX, 10362, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10364, UINT16_MAX, 10364, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10366, UINT16_MAX, 10366, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10368, UINT16_MAX, 10368, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10370, UINT16_MAX, 10370, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10372, UINT16_MAX, 10372, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10374, UINT16_MAX, 10374, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10376, UINT16_MAX, 10376, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10378, UINT16_MAX, 10378, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10380, UINT16_MAX, 10380, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10382, UINT16_MAX, 10382, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10384, UINT16_MAX, 10384, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10386, UINT16_MAX, 10386, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10388, UINT16_MAX, 10388, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10390, UINT16_MAX, 10390, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10392, UINT16_MAX, 10392, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10394, UINT16_MAX, 10394, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10396, UINT16_MAX, 10396, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 10398, UINT16_MAX, 10398, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MC, 6, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5374, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5378, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23761, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23765, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5382, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23769, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23773, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23777, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23781, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49224, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 226, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_SPACINGMARK}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49226, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49228, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49230, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49232, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 49234, false, false, false, false, 0, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5394, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5398, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23789, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5402, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, 5408, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23805, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, 23809, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, true, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 10400, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 10402, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 10404, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 10406, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 10408, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 10410, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 10412, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 10414, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 10416, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 10418, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 10420, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 10422, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 10424, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 10426, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 10428, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 10430, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 10432, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 10434, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 10436, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 10438, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 10440, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 10442, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 10444, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 10446, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 10448, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 10450, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 10452, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 10454, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 10456, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 10458, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 10460, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 10462, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 10464, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 10466, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 10468, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 10470, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 10472, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 10474, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 10476, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 10478, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 10480, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 10482, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 10484, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 10486, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 10488, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 10490, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 10492, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 10494, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 10496, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 10498, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 10500, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 10502, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 10504, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 10506, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 10508, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 10510, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 10512, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 10514, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 10516, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 10518, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 10520, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 10522, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 10524, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 10526, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 10528, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 10530, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 10532, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 10534, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 10536, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 10538, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 10540, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 10542, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 10544, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 10546, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 10548, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 10550, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 10552, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 10554, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 10556, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 10558, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 10560, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 10562, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 10564, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 10566, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 10568, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 10570, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 10572, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 10574, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 10576, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 10578, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 10580, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 10582, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 10584, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 10586, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 10588, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 10590, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 10592, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 10594, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 10596, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 10598, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 10600, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 10602, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 10604, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 10606, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 10608, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 10610, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 10612, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 10614, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 10616, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 10618, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 10620, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 10622, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 10624, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 10626, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 10628, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 10630, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 10632, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 10634, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 10636, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 10638, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 10640, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 10642, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 10644, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 10646, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 10648, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 10650, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 10652, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 10654, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 10656, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 10658, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 10660, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 10662, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 10664, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 10666, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 10668, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 10670, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 10672, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 10674, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 10676, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 10678, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 10680, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 10682, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 10684, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 10686, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 10688, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 10690, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 10692, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 10694, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 10696, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 10698, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 10700, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 10702, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 10704, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 10706, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 10708, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 10710, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 10712, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 10714, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 10716, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 10718, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 10720, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 10722, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 10724, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 10726, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 10728, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 10730, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 10732, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 10734, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 10736, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 10738, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 10740, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 10742, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 10744, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 10746, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 10748, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 10750, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 10752, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 10754, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 10756, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 10758, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 10760, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 10762, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 10764, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 10766, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 10768, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 10770, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 10772, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 10774, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 10776, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 10778, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 10780, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 10782, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 10784, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 10786, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 10788, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 10790, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 10792, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 10794, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 10796, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 10798, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 10800, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 10802, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 10804, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 10806, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 10808, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 10810, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 10812, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 10814, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 10816, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 10818, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 10820, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 10822, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 10824, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 10826, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 10828, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 10830, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 10832, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 10834, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 10836, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 10838, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 10840, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 10842, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 10844, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 10846, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 10848, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 10850, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 10852, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 10854, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 10856, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 10858, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 10860, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 10862, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 10864, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 10866, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 10868, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 10870, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 10872, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 10874, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 10876, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 10878, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 10880, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 10882, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 10884, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 10886, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 10888, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 10890, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 10892, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 10894, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 10896, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 10898, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 10900, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 10902, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 10904, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 10906, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 10908, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 10910, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 10912, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 10914, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 10916, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 10918, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 10920, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 10922, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 10924, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 10926, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 10928, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 10930, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 10932, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 10934, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 10936, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 10938, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 10940, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 10942, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 10944, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 10946, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 10948, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 10950, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 10952, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 10954, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 10956, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 10958, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 10960, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 10962, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 10964, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 10966, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 10968, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 10970, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 10972, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 10974, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 10976, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 10978, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 10980, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 10982, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 10984, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 10986, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 10988, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 10990, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 10992, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 10994, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 10996, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 10998, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 11000, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 11002, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 11004, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 11006, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 11008, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 11010, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 11012, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 11014, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 11016, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 11018, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 11020, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 11022, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 11024, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 11026, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 11028, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 11030, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 11032, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 11034, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 11036, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 11038, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 11040, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 11042, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 11044, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 11046, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 11048, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 11050, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 11052, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 11054, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 11056, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 11058, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 11060, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 11062, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 11064, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 11066, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 11068, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 11070, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 11072, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 11074, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 11076, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 11078, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 11080, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 11082, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 11084, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 11086, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 11088, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 11090, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 11092, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 11094, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 11096, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 11098, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 11100, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 11102, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 11104, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 11106, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 11108, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 11110, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 11112, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 11114, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 11116, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 11118, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 11120, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 11122, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 11124, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 11126, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 11128, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 11130, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 11132, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 11134, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 11136, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 11138, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 11140, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 11142, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 11144, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 11146, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 11148, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 11150, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 11152, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 11154, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 11156, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 11158, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 11160, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 11162, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 11164, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 11166, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 11168, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 11170, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 11172, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 11174, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 11176, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 11178, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 11180, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 11182, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 11184, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 11186, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 11188, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 11190, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 11192, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 11194, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 11196, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 11198, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 11200, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 11202, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 11204, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 11206, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 11208, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 11210, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 11212, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 11214, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 11216, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 11218, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 11220, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 11222, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 11224, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 11226, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 11228, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 11230, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 11232, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 11234, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 11236, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 11238, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 11240, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 11242, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 11244, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 11246, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 11248, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 11250, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 11252, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 11254, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 11256, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 11258, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 11260, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 11262, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 11264, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 11266, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 11268, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 11270, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 11272, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 11274, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 11276, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 11278, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 11280, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 11282, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 11284, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 11286, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 11288, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 11290, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 11292, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 11294, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 11296, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 11298, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 11300, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 11302, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 11304, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 11306, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 11308, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 11310, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 11312, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 11314, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 11316, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 11318, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 11320, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 11322, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 11324, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 11326, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 11328, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 11330, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 11332, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 11334, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 11336, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 11338, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 11340, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 11342, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 11344, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 11346, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 11348, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 11350, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 11352, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 11354, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 11356, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 11358, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 11360, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 11362, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 11364, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 11366, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 11368, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 11370, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 11372, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 11374, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 11376, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 11378, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 11380, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 11382, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 11384, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 11386, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 11388, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 11390, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 11392, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 11394, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 11396, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 11398, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 11400, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 11402, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 11404, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 11406, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 11408, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 11410, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 11412, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 11414, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 11416, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 11418, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 11420, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 11422, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 11424, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 11426, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 11428, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 11430, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 11432, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 11434, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 11436, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 11438, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 11440, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 11442, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 11444, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 11446, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 11448, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 11450, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 11452, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 11454, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 11456, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 11458, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 11460, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 11462, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 11464, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 11466, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 11468, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 11470, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 11472, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 11474, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 11476, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 11478, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 11480, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 11482, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 11484, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 11486, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 11488, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 11490, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 11492, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 11494, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 11496, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 11498, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 11500, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 11502, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 11504, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 11506, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 11508, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 11510, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 11512, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 11514, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 11516, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 11518, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 11520, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 11522, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 11524, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 11526, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 11528, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 11530, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 11532, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 11534, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 11536, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 11538, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 11540, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 11542, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 11544, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 11546, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 11548, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 11550, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 11552, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 11554, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 11556, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 11558, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 11560, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 11562, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 11564, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 11566, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 11568, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 11570, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 11572, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 11574, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 11576, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 11578, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 11580, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 11582, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 11584, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 11586, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 11588, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 11590, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 11592, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 11594, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 11596, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 11598, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1491, UINT16_MAX, UINT16_MAX, 11600, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1493, UINT16_MAX, UINT16_MAX, 11602, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2813, UINT16_MAX, UINT16_MAX, 11604, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1494, UINT16_MAX, UINT16_MAX, 11606, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1495, UINT16_MAX, UINT16_MAX, 11608, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2838, UINT16_MAX, UINT16_MAX, 11610, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1497, UINT16_MAX, UINT16_MAX, 11612, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1498, UINT16_MAX, UINT16_MAX, 11614, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1499, UINT16_MAX, UINT16_MAX, 11616, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1500, UINT16_MAX, UINT16_MAX, 11618, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1501, UINT16_MAX, UINT16_MAX, 11620, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1502, UINT16_MAX, UINT16_MAX, 11622, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1503, UINT16_MAX, UINT16_MAX, 11624, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1504, UINT16_MAX, UINT16_MAX, 11626, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1505, UINT16_MAX, UINT16_MAX, 11628, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1507, UINT16_MAX, UINT16_MAX, 11630, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2827, UINT16_MAX, UINT16_MAX, 11632, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1508, UINT16_MAX, UINT16_MAX, 11634, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3320, UINT16_MAX, UINT16_MAX, 11636, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1509, UINT16_MAX, UINT16_MAX, 11638, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1510, UINT16_MAX, UINT16_MAX, 11640, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2910, UINT16_MAX, UINT16_MAX, 11642, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1511, UINT16_MAX, UINT16_MAX, 11644, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2928, UINT16_MAX, UINT16_MAX, 11646, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3327, UINT16_MAX, UINT16_MAX, 11648, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2835, UINT16_MAX, UINT16_MAX, 11650, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 0, UINT16_MAX, 11652, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 1, UINT16_MAX, 11654, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2, UINT16_MAX, 11656, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 3, UINT16_MAX, 11658, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 4, UINT16_MAX, 11660, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 5, UINT16_MAX, 11662, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 6, UINT16_MAX, 11664, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7, UINT16_MAX, 11666, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 8, UINT16_MAX, 11668, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 9, UINT16_MAX, 11670, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 10, UINT16_MAX, 11672, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 11, UINT16_MAX, 11674, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 12, UINT16_MAX, 11676, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 13, UINT16_MAX, 11678, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 14, UINT16_MAX, 11680, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 15, UINT16_MAX, 11682, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 16, UINT16_MAX, 11684, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 17, UINT16_MAX, 11686, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 18, UINT16_MAX, 11688, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 19, UINT16_MAX, 11690, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 20, UINT16_MAX, 11692, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 21, UINT16_MAX, 11694, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 22, UINT16_MAX, 11696, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 23, UINT16_MAX, 11698, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 24, UINT16_MAX, 11700, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 25, UINT16_MAX, 11702, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7429, UINT16_MAX, 11704, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7430, UINT16_MAX, 11706, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7431, UINT16_MAX, UINT16_MAX, 11708, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7432, UINT16_MAX, UINT16_MAX, 11710, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2847, UINT16_MAX, UINT16_MAX, 11712, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7433, UINT16_MAX, UINT16_MAX, 11714, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7434, UINT16_MAX, UINT16_MAX, 11716, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7435, UINT16_MAX, UINT16_MAX, 11718, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7436, UINT16_MAX, UINT16_MAX, 11720, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 915, UINT16_MAX, UINT16_MAX, 11722, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7437, UINT16_MAX, UINT16_MAX, 11724, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7438, UINT16_MAX, UINT16_MAX, 11726, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7439, UINT16_MAX, UINT16_MAX, 11728, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7440, UINT16_MAX, UINT16_MAX, 11730, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7441, UINT16_MAX, UINT16_MAX, 11732, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7442, UINT16_MAX, UINT16_MAX, 11734, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7443, UINT16_MAX, UINT16_MAX, 11736, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2848, UINT16_MAX, UINT16_MAX, 11738, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7444, UINT16_MAX, UINT16_MAX, 11740, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7445, UINT16_MAX, UINT16_MAX, 11742, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 917, UINT16_MAX, UINT16_MAX, 11744, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7446, UINT16_MAX, UINT16_MAX, 11746, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 897, UINT16_MAX, UINT16_MAX, 11748, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7447, UINT16_MAX, UINT16_MAX, 11750, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7448, UINT16_MAX, UINT16_MAX, 11752, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7449, UINT16_MAX, UINT16_MAX, 11754, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2836, UINT16_MAX, UINT16_MAX, 11756, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7450, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 845, UINT16_MAX, 11758, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 846, UINT16_MAX, 11760, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 847, UINT16_MAX, 11762, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 848, UINT16_MAX, 11764, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 849, UINT16_MAX, 11766, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 850, UINT16_MAX, 11768, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 851, UINT16_MAX, 11770, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 852, UINT16_MAX, 11772, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 807, UINT16_MAX, 11774, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 853, UINT16_MAX, 11776, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 854, UINT16_MAX, 11778, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 35, UINT16_MAX, 11780, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 855, UINT16_MAX, 11782, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 856, UINT16_MAX, 11784, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 857, UINT16_MAX, 11786, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 858, UINT16_MAX, 11788, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 859, UINT16_MAX, 11790, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 914, UINT16_MAX, 11792, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 860, UINT16_MAX, 11794, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 861, UINT16_MAX, 11796, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 862, UINT16_MAX, 11798, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 863, UINT16_MAX, 11800, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 864, UINT16_MAX, 11802, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 865, UINT16_MAX, 11804, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 866, UINT16_MAX, 11806, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FONT, 7451, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, true, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7452, UINT16_MAX, 11808, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7453, UINT16_MAX, 11810, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7454, UINT16_MAX, 11812, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7455, UINT16_MAX, 11814, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7456, UINT16_MAX, 11816, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7457, UINT16_MAX, 11818, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7431, UINT16_MAX, UINT16_MAX, 11820, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7432, UINT16_MAX, UINT16_MAX, 11822, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2847, UINT16_MAX, UINT16_MAX, 11824, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7433, UINT16_MAX, UINT16_MAX, 11826, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7434, UINT16_MAX, UINT16_MAX, 11828, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7435, UINT16_MAX, UINT16_MAX, 11830, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7436, UINT16_MAX, UINT16_MAX, 11832, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 915, UINT16_MAX, UINT16_MAX, 11834, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7437, UINT16_MAX, UINT16_MAX, 11836, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7438, UINT16_MAX, UINT16_MAX, 11838, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7439, UINT16_MAX, UINT16_MAX, 11840, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7440, UINT16_MAX, UINT16_MAX, 11842, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7441, UINT16_MAX, UINT16_MAX, 11844, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7442, UINT16_MAX, UINT16_MAX, 11846, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7443, UINT16_MAX, UINT16_MAX, 11848, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2848, UINT16_MAX, UINT16_MAX, 11850, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7444, UINT16_MAX, UINT16_MAX, 11852, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7445, UINT16_MAX, UINT16_MAX, 11854, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 917, UINT16_MAX, UINT16_MAX, 11856, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7446, UINT16_MAX, UINT16_MAX, 11858, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 897, UINT16_MAX, UINT16_MAX, 11860, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7447, UINT16_MAX, UINT16_MAX, 11862, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7448, UINT16_MAX, UINT16_MAX, 11864, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7449, UINT16_MAX, UINT16_MAX, 11866, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2836, UINT16_MAX, UINT16_MAX, 11868, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 845, UINT16_MAX, 11870, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 846, UINT16_MAX, 11872, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 847, UINT16_MAX, 11874, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 848, UINT16_MAX, 11876, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 849, UINT16_MAX, 11878, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 850, UINT16_MAX, 11880, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 851, UINT16_MAX, 11882, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 852, UINT16_MAX, 11884, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 807, UINT16_MAX, 11886, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 853, UINT16_MAX, 11888, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 854, UINT16_MAX, 11890, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 35, UINT16_MAX, 11892, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 855, UINT16_MAX, 11894, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 856, UINT16_MAX, 11896, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 857, UINT16_MAX, 11898, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 858, UINT16_MAX, 11900, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 859, UINT16_MAX, 11902, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 914, UINT16_MAX, 11904, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 860, UINT16_MAX, 11906, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 861, UINT16_MAX, 11908, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 862, UINT16_MAX, 11910, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 863, UINT16_MAX, 11912, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 864, UINT16_MAX, 11914, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 865, UINT16_MAX, 11916, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 866, UINT16_MAX, 11918, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7452, UINT16_MAX, 11920, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7453, UINT16_MAX, 11922, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7454, UINT16_MAX, 11924, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7455, UINT16_MAX, 11926, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7456, UINT16_MAX, 11928, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7457, UINT16_MAX, 11930, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7431, UINT16_MAX, UINT16_MAX, 11932, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7432, UINT16_MAX, UINT16_MAX, 11934, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2847, UINT16_MAX, UINT16_MAX, 11936, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7433, UINT16_MAX, UINT16_MAX, 11938, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7434, UINT16_MAX, UINT16_MAX, 11940, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7435, UINT16_MAX, UINT16_MAX, 11942, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7436, UINT16_MAX, UINT16_MAX, 11944, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 915, UINT16_MAX, UINT16_MAX, 11946, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7437, UINT16_MAX, UINT16_MAX, 11948, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7438, UINT16_MAX, UINT16_MAX, 11950, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7439, UINT16_MAX, UINT16_MAX, 11952, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7440, UINT16_MAX, UINT16_MAX, 11954, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7441, UINT16_MAX, UINT16_MAX, 11956, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7442, UINT16_MAX, UINT16_MAX, 11958, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7443, UINT16_MAX, UINT16_MAX, 11960, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2848, UINT16_MAX, UINT16_MAX, 11962, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7444, UINT16_MAX, UINT16_MAX, 11964, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7445, UINT16_MAX, UINT16_MAX, 11966, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 917, UINT16_MAX, UINT16_MAX, 11968, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7446, UINT16_MAX, UINT16_MAX, 11970, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 897, UINT16_MAX, UINT16_MAX, 11972, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7447, UINT16_MAX, UINT16_MAX, 11974, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7448, UINT16_MAX, UINT16_MAX, 11976, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7449, UINT16_MAX, UINT16_MAX, 11978, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2836, UINT16_MAX, UINT16_MAX, 11980, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 845, UINT16_MAX, 11982, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 846, UINT16_MAX, 11984, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 847, UINT16_MAX, 11986, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 848, UINT16_MAX, 11988, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 849, UINT16_MAX, 11990, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 850, UINT16_MAX, 11992, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 851, UINT16_MAX, 11994, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 852, UINT16_MAX, 11996, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 807, UINT16_MAX, 11998, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 853, UINT16_MAX, 12000, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 854, UINT16_MAX, 12002, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 35, UINT16_MAX, 12004, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 855, UINT16_MAX, 12006, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 856, UINT16_MAX, 12008, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 857, UINT16_MAX, 12010, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 858, UINT16_MAX, 12012, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 859, UINT16_MAX, 12014, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 914, UINT16_MAX, 12016, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 860, UINT16_MAX, 12018, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 861, UINT16_MAX, 12020, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 862, UINT16_MAX, 12022, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 863, UINT16_MAX, 12024, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 864, UINT16_MAX, 12026, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 865, UINT16_MAX, 12028, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 866, UINT16_MAX, 12030, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7452, UINT16_MAX, 12032, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7453, UINT16_MAX, 12034, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7454, UINT16_MAX, 12036, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7455, UINT16_MAX, 12038, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7456, UINT16_MAX, 12040, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7457, UINT16_MAX, 12042, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7431, UINT16_MAX, UINT16_MAX, 12044, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7432, UINT16_MAX, UINT16_MAX, 12046, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2847, UINT16_MAX, UINT16_MAX, 12048, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7433, UINT16_MAX, UINT16_MAX, 12050, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7434, UINT16_MAX, UINT16_MAX, 12052, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7435, UINT16_MAX, UINT16_MAX, 12054, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7436, UINT16_MAX, UINT16_MAX, 12056, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 915, UINT16_MAX, UINT16_MAX, 12058, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7437, UINT16_MAX, UINT16_MAX, 12060, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7438, UINT16_MAX, UINT16_MAX, 12062, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7439, UINT16_MAX, UINT16_MAX, 12064, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7440, UINT16_MAX, UINT16_MAX, 12066, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7441, UINT16_MAX, UINT16_MAX, 12068, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7442, UINT16_MAX, UINT16_MAX, 12070, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7443, UINT16_MAX, UINT16_MAX, 12072, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2848, UINT16_MAX, UINT16_MAX, 12074, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7444, UINT16_MAX, UINT16_MAX, 12076, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7445, UINT16_MAX, UINT16_MAX, 12078, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 917, UINT16_MAX, UINT16_MAX, 12080, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7446, UINT16_MAX, UINT16_MAX, 12082, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 897, UINT16_MAX, UINT16_MAX, 12084, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7447, UINT16_MAX, UINT16_MAX, 12086, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7448, UINT16_MAX, UINT16_MAX, 12088, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7449, UINT16_MAX, UINT16_MAX, 12090, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2836, UINT16_MAX, UINT16_MAX, 12092, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 845, UINT16_MAX, 12094, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 846, UINT16_MAX, 12096, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 847, UINT16_MAX, 12098, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 848, UINT16_MAX, 12100, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 849, UINT16_MAX, 12102, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 850, UINT16_MAX, 12104, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 851, UINT16_MAX, 12106, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 852, UINT16_MAX, 12108, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 807, UINT16_MAX, 12110, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 853, UINT16_MAX, 12112, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 854, UINT16_MAX, 12114, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 35, UINT16_MAX, 12116, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 855, UINT16_MAX, 12118, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 856, UINT16_MAX, 12120, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 857, UINT16_MAX, 12122, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 858, UINT16_MAX, 12124, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 859, UINT16_MAX, 12126, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 914, UINT16_MAX, 12128, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 860, UINT16_MAX, 12130, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 861, UINT16_MAX, 12132, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 862, UINT16_MAX, 12134, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 863, UINT16_MAX, 12136, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 864, UINT16_MAX, 12138, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 865, UINT16_MAX, 12140, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 866, UINT16_MAX, 12142, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7452, UINT16_MAX, 12144, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7453, UINT16_MAX, 12146, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7454, UINT16_MAX, 12148, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7455, UINT16_MAX, 12150, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7456, UINT16_MAX, 12152, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7457, UINT16_MAX, 12154, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7431, UINT16_MAX, UINT16_MAX, 12156, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7432, UINT16_MAX, UINT16_MAX, 12158, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2847, UINT16_MAX, UINT16_MAX, 12160, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7433, UINT16_MAX, UINT16_MAX, 12162, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7434, UINT16_MAX, UINT16_MAX, 12164, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7435, UINT16_MAX, UINT16_MAX, 12166, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7436, UINT16_MAX, UINT16_MAX, 12168, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 915, UINT16_MAX, UINT16_MAX, 12170, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7437, UINT16_MAX, UINT16_MAX, 12172, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7438, UINT16_MAX, UINT16_MAX, 12174, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7439, UINT16_MAX, UINT16_MAX, 12176, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7440, UINT16_MAX, UINT16_MAX, 12178, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7441, UINT16_MAX, UINT16_MAX, 12180, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7442, UINT16_MAX, UINT16_MAX, 12182, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7443, UINT16_MAX, UINT16_MAX, 12184, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2848, UINT16_MAX, UINT16_MAX, 12186, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7444, UINT16_MAX, UINT16_MAX, 12188, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7445, UINT16_MAX, UINT16_MAX, 12190, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 917, UINT16_MAX, UINT16_MAX, 12192, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7446, UINT16_MAX, UINT16_MAX, 12194, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 897, UINT16_MAX, UINT16_MAX, 12196, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7447, UINT16_MAX, UINT16_MAX, 12198, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7448, UINT16_MAX, UINT16_MAX, 12200, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7449, UINT16_MAX, UINT16_MAX, 12202, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 2836, UINT16_MAX, UINT16_MAX, 12204, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 845, UINT16_MAX, 12206, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 846, UINT16_MAX, 12208, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 847, UINT16_MAX, 12210, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 848, UINT16_MAX, 12212, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 849, UINT16_MAX, 12214, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 850, UINT16_MAX, 12216, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 851, UINT16_MAX, 12218, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 852, UINT16_MAX, 12220, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 807, UINT16_MAX, 12222, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 853, UINT16_MAX, 12224, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 854, UINT16_MAX, 12226, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 35, UINT16_MAX, 12228, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 855, UINT16_MAX, 12230, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 856, UINT16_MAX, 12232, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 857, UINT16_MAX, 12234, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 858, UINT16_MAX, 12236, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 859, UINT16_MAX, 12238, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 914, UINT16_MAX, 12240, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 860, UINT16_MAX, 12242, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 861, UINT16_MAX, 12244, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 862, UINT16_MAX, 12246, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 863, UINT16_MAX, 12248, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 864, UINT16_MAX, 12250, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 865, UINT16_MAX, 12252, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 866, UINT16_MAX, 12254, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7452, UINT16_MAX, 12256, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7453, UINT16_MAX, 12258, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7454, UINT16_MAX, 12260, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7455, UINT16_MAX, 12262, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7456, UINT16_MAX, 12264, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7457, UINT16_MAX, 12266, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 7458, UINT16_MAX, UINT16_MAX, 12268, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, 904, UINT16_MAX, 12270, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 38, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 31, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 32, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2798, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, 2799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12272, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12274, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12276, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12278, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7064, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7068, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7071, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12280, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7076, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12282, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12284, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12286, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12288, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12290, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12292, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12294, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12296, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12298, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12300, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12302, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12304, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12306, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12308, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12310, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12312, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12314, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12316, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12318, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12320, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 7093, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12322, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12324, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12326, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12328, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12330, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, 12332, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 953, UINT16_MAX, 12334, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 954, UINT16_MAX, 12336, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 955, UINT16_MAX, 12338, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 956, UINT16_MAX, 12340, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 957, UINT16_MAX, 12342, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 958, UINT16_MAX, 12344, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 959, UINT16_MAX, 12346, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 960, UINT16_MAX, 12348, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 961, UINT16_MAX, 12350, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 965, UINT16_MAX, 12352, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 966, UINT16_MAX, 12354, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 967, UINT16_MAX, 12356, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 969, UINT16_MAX, 12358, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 970, UINT16_MAX, 12360, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 971, UINT16_MAX, 12362, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 972, UINT16_MAX, 12364, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 973, UINT16_MAX, 12366, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 974, UINT16_MAX, 12368, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 975, UINT16_MAX, 12370, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 976, UINT16_MAX, 12372, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 977, UINT16_MAX, 12374, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 978, UINT16_MAX, 12376, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 979, UINT16_MAX, 12378, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 982, UINT16_MAX, 12380, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 984, UINT16_MAX, 12382, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 985, UINT16_MAX, 12384, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5162, UINT16_MAX, 12386, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1079, UINT16_MAX, 12388, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 935, UINT16_MAX, 12390, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 939, UINT16_MAX, 12392, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1111, UINT16_MAX, 12394, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1042, UINT16_MAX, 12396, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1051, UINT16_MAX, 12398, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 953, UINT16_MAX, 12400, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 954, UINT16_MAX, 12402, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 955, UINT16_MAX, 12404, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 956, UINT16_MAX, 12406, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 957, UINT16_MAX, 12408, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 958, UINT16_MAX, 12410, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 959, UINT16_MAX, 12412, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 960, UINT16_MAX, 12414, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 961, UINT16_MAX, 12416, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 965, UINT16_MAX, 12418, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 966, UINT16_MAX, 12420, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 969, UINT16_MAX, 12422, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 970, UINT16_MAX, 12424, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 972, UINT16_MAX, 12426, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 974, UINT16_MAX, 12428, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 975, UINT16_MAX, 12430, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 976, UINT16_MAX, 12432, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 977, UINT16_MAX, 12434, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 978, UINT16_MAX, 12436, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 979, UINT16_MAX, 12438, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 981, UINT16_MAX, 12440, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 982, UINT16_MAX, 12442, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 1027, UINT16_MAX, 12444, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 935, UINT16_MAX, 12446, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 934, UINT16_MAX, 12448, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, 952, UINT16_MAX, 12450, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1040, UINT16_MAX, 12452, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 5143, UINT16_MAX, 12454, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, 1043, UINT16_MAX, 12456, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7459, UINT16_MAX, 7459, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7461, UINT16_MAX, 7461, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7463, UINT16_MAX, 7463, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7465, UINT16_MAX, 7465, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7467, UINT16_MAX, 7467, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7469, UINT16_MAX, 7469, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7471, UINT16_MAX, 7471, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7473, UINT16_MAX, 7473, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7475, UINT16_MAX, 7475, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7477, UINT16_MAX, 7477, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7479, UINT16_MAX, 7479, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7481, UINT16_MAX, 7481, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7483, UINT16_MAX, 7483, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7485, UINT16_MAX, 7485, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7487, UINT16_MAX, 7487, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7489, UINT16_MAX, 7489, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7491, UINT16_MAX, 7491, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7493, UINT16_MAX, 7493, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7495, UINT16_MAX, 7495, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7497, UINT16_MAX, 7497, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7499, UINT16_MAX, 7499, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7501, UINT16_MAX, 7501, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7503, UINT16_MAX, 7503, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7505, UINT16_MAX, 7505, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7507, UINT16_MAX, 7507, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7509, UINT16_MAX, 7509, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7511, UINT16_MAX, 7511, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7513, UINT16_MAX, 7513, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7515, UINT16_MAX, 7515, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7517, UINT16_MAX, 7517, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7519, UINT16_MAX, 7519, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7521, UINT16_MAX, 7521, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7523, UINT16_MAX, 7523, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, 7525, UINT16_MAX, 7525, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12458, UINT16_MAX, 12458, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12460, UINT16_MAX, 12460, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12462, UINT16_MAX, 12462, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12464, UINT16_MAX, 12464, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12466, UINT16_MAX, 12466, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12468, UINT16_MAX, 12468, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12470, UINT16_MAX, 12470, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12472, UINT16_MAX, 12472, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12474, UINT16_MAX, 12474, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12476, UINT16_MAX, 12476, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12478, UINT16_MAX, 12478, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12480, UINT16_MAX, 12480, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12482, UINT16_MAX, 12482, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12484, UINT16_MAX, 12484, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12486, UINT16_MAX, 12486, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12488, UINT16_MAX, 12488, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12490, UINT16_MAX, 12490, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12492, UINT16_MAX, 12492, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12494, UINT16_MAX, 12494, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12496, UINT16_MAX, 12496, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12498, UINT16_MAX, 12498, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12500, UINT16_MAX, 12500, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12502, UINT16_MAX, 12502, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12504, UINT16_MAX, 12504, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12506, UINT16_MAX, 12506, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12508, UINT16_MAX, 12508, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12510, UINT16_MAX, 12510, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12512, UINT16_MAX, 12512, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12514, UINT16_MAX, 12514, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12516, UINT16_MAX, 12516, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12518, UINT16_MAX, 12518, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12520, UINT16_MAX, 12520, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12522, UINT16_MAX, 12522, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_R, 0, UINT16_MAX, UINT16_MAX, 12524, UINT16_MAX, 12524, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6677, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6680, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6699, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6683, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6678, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6700, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6694, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6695, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6696, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6697, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6692, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6693, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6682, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6681, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6691, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 7527, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 5874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 7528, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 7529, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FONT, 6698, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23914, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23916, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23918, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23920, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23922, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23924, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23926, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23928, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23930, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23932, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, 23934, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40320, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40323, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40326, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40329, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40332, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40335, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40338, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40341, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40344, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40347, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40350, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40353, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40356, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40359, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40362, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40365, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40368, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40371, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40374, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40377, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40380, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40383, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40386, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40389, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40392, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40395, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40398, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 2813, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 1508, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 24017, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 24019, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1491, UINT16_MAX, UINT16_MAX, 12526, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1493, UINT16_MAX, UINT16_MAX, 12528, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2813, UINT16_MAX, UINT16_MAX, 12530, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1494, UINT16_MAX, UINT16_MAX, 12532, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1495, UINT16_MAX, UINT16_MAX, 12534, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2838, UINT16_MAX, UINT16_MAX, 12536, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1497, UINT16_MAX, UINT16_MAX, 12538, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1498, UINT16_MAX, UINT16_MAX, 12540, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1499, UINT16_MAX, UINT16_MAX, 12542, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1500, UINT16_MAX, UINT16_MAX, 12544, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1501, UINT16_MAX, UINT16_MAX, 12546, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1502, UINT16_MAX, UINT16_MAX, 12548, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1503, UINT16_MAX, UINT16_MAX, 12550, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1504, UINT16_MAX, UINT16_MAX, 12552, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1505, UINT16_MAX, UINT16_MAX, 12554, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1507, UINT16_MAX, UINT16_MAX, 12556, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2827, UINT16_MAX, UINT16_MAX, 12558, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1508, UINT16_MAX, UINT16_MAX, 12560, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3320, UINT16_MAX, UINT16_MAX, 12562, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1509, UINT16_MAX, UINT16_MAX, 12564, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1510, UINT16_MAX, UINT16_MAX, 12566, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2910, UINT16_MAX, UINT16_MAX, 12568, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 1511, UINT16_MAX, UINT16_MAX, 12570, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2928, UINT16_MAX, UINT16_MAX, 12572, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3327, UINT16_MAX, UINT16_MAX, 12574, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 2835, UINT16_MAX, UINT16_MAX, 12576, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 24021, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 21339, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 24023, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 24025, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 40411, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 24030, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12578, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12580, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12582, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12584, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12586, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12588, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12590, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12592, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12594, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12596, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12598, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12600, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12602, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12604, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12606, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12608, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12610, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12612, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12614, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12616, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12618, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12620, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12622, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12624, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12626, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12628, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 24032, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 24034, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, 24036, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12630, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12632, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12634, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12636, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12638, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12640, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12642, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12644, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12646, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12648, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12650, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12652, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12654, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12656, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12658, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12660, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12662, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12664, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12666, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12668, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12670, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12672, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12674, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12676, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12678, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, 12680, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 24038, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 1, 0, UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 24040, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 24042, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 4331, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3523, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7660, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7661, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7662, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3466, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7663, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7664, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3903, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7665, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7666, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7667, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 5513, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7669, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7670, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7671, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7672, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7673, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3559, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7674, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7675, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7676, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7677, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7678, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7679, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3460, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3895, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7680, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 4244, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3898, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 4245, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7681, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3615, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7682, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7683, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7684, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7685, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7686, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 4227, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 3533, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7687, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7689, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, 7690, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40459, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40462, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40465, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40468, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40471, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40474, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40477, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40480, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, 40483, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 7718, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, 7719, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_EXTEND}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7720, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7721, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7722, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7723, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7725, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7726, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7727, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7728, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7729, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7730, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7731, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7732, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7734, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7735, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7736, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7737, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7739, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7740, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7670, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7741, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7743, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7744, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7745, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7746, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7747, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3476, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7749, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7750, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7751, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7752, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7688, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7753, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7754, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7755, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7756, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7757, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7758, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7759, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7760, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7761, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7762, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7764, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7765, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7766, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7767, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7769, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7770, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7771, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7772, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7773, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7774, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7775, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7776, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7777, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7778, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7779, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7780, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7781, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7782, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7783, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7784, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7785, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7786, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7787, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7788, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7789, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7790, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7791, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7792, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7793, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7794, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7795, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7796, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7797, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7799, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7800, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7801, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7663, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7802, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7803, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7804, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7806, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7808, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7809, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7810, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7811, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7812, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7813, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7814, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7815, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7816, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7817, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7819, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7820, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7821, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7822, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7824, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7825, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7826, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3502, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7827, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7828, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7829, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7830, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7831, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7833, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7834, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7836, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7837, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7838, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7839, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7840, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7841, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7842, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7843, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7844, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7845, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7846, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7847, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7849, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7850, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7851, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7852, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7853, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3514, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7855, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7857, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7858, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7859, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7860, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7862, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7864, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7865, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7866, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7867, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7868, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7869, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7870, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7871, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7872, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7873, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7874, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7876, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7877, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7878, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7879, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7880, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7881, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7882, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7883, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7884, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7885, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7886, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7887, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7888, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7889, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7890, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7892, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7893, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7894, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7895, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7896, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7897, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7899, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7900, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7901, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7902, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7903, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7904, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7905, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7906, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7907, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7908, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7909, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7911, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7912, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7913, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7914, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7915, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7916, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7917, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7918, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7919, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7920, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7921, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7922, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7923, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7924, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7925, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7926, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7928, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7929, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7930, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7931, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7932, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7934, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7935, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7936, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7937, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7938, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7939, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7940, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7941, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7943, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7944, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7945, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7946, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7948, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7949, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7950, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7951, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7952, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7953, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7955, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7957, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7959, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7960, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7962, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7963, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7964, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7965, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7966, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7967, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7968, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7969, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7970, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7972, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7973, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7974, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7975, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7976, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7977, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7979, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7980, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7981, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7983, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7985, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7986, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7987, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7988, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7989, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7990, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7991, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7992, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7993, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7995, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7996, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7998, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 7999, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8001, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8002, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8003, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8005, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8006, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8007, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8009, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8011, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8012, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8013, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8014, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8015, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8016, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8017, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8018, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8019, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8020, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8021, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8022, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8024, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8025, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8027, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8029, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8030, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8032, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8034, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8036, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8037, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8038, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8040, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8042, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8044, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8046, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8047, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8048, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8049, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8050, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8051, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8053, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8054, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8055, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8057, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8059, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8061, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8062, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8063, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8064, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8065, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8067, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8069, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8070, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8071, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8073, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8074, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8075, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8076, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8078, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8079, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8080, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8081, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8082, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8083, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8085, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8086, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8087, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8088, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8089, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8090, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8091, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8093, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8095, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8096, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8098, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8099, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8101, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8102, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8103, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8105, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8107, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8108, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8110, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8111, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8113, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8114, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8115, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8116, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8117, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8118, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8119, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8121, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8123, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8125, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8127, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8128, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8129, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8130, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8131, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8132, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8133, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8134, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8135, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8136, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8137, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8138, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8140, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8141, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8142, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8143, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8144, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8145, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8146, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8147, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8148, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8149, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8150, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8152, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8154, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8156, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8157, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8158, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8159, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8160, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8162, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8163, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8165, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8166, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8167, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8169, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8171, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8172, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8173, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8174, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8175, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8176, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8177, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8178, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8179, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8180, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8181, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8182, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8183, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8184, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8185, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8186, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3604, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8187, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8189, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8190, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8191, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8192, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8193, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8194, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8196, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8198, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8199, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8200, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3611, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8201, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8203, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8204, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8205, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8206, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8207, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8209, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8211, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8212, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8213, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8214, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8216, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8217, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8219, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8221, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8222, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8223, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8224, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8226, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8227, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8228, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8229, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8230, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8231, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8232, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8233, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8235, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8236, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8237, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8238, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8240, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8241, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8242, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8243, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8244, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8246, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8248, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8249, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8250, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8251, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8253, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8254, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8256, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8257, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8259, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8260, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8261, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8262, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8263, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8264, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8265, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8266, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8268, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8269, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8270, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8271, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8272, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8273, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8275, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8276, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8278, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8280, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3659, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8282, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3663, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8283, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8284, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8285, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8286, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 3668, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, 8287, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, false, false, false, false, 2, 0, UTF8PROC_BOUNDCLASS_OTHER}, +}; + +static const utf8proc_uint16_t utf8proc_combinations[] = { + 0, 46, 192, 193, 194, 195, 196, 197, 0, + 256, 258, 260, 550, 461, 0, 0, 512, + 514, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7680, 7840, 0, 0, 0, 0, 0, 7842, +1, 11, + 262, 264, 0, 0, 0, 199, 0, 0, + 0, 266, 268, +0, 46, 200, 201, 202, 7868, 203, + 0, 552, 274, 276, 280, 278, 282, 0, + 0, 516, 518, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7864, 0, 7704, 7706, 0, + 0, 7866, +0, 46, 204, 205, 206, 296, 207, 0, + 0, 298, 300, 302, 304, 463, 0, 0, + 520, 522, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7882, 0, 0, 7724, 0, 0, + 7880, +0, 42, 504, 323, 0, 209, 0, 0, 325, + 0, 0, 0, 7748, 327, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7750, 7752, 7754, +0, 46, 210, 211, 212, 213, + 214, 0, 0, 332, 334, 490, 558, 465, + 336, 416, 524, 526, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7884, 0, 0, 0, + 0, 0, 7886, +0, 46, 217, 218, 219, 360, 220, + 366, 0, 362, 364, 370, 0, 467, 368, + 431, 532, 534, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7908, 0, 7798, 7796, 0, + 7794, 7910, +0, 46, 7922, 221, 374, 7928, 376, 0, + 0, 562, 0, 0, 7822, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7924, 0, 0, 0, 0, 0, + 7926, +0, 46, 224, 225, 226, 227, 228, 229, 0, + 257, 259, 261, 551, 462, 0, 0, 513, + 515, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7681, 7841, 0, 0, 0, 0, 0, 7843, +1, 11, + 263, 265, 0, 0, 0, 231, 0, 0, + 0, 267, 269, +0, 46, 232, 233, 234, 7869, 235, + 0, 553, 275, 277, 281, 279, 283, 0, + 0, 517, 519, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7865, 0, 7705, 7707, 0, + 0, 7867, +0, 46, 236, 237, 238, 297, 239, 0, + 0, 299, 301, 303, 0, 464, 0, 0, + 521, 523, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7883, 0, 0, 7725, 0, 0, + 7881, +0, 42, 505, 324, 0, 241, 0, 0, 326, + 0, 0, 0, 7749, 328, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7751, 7753, 7755, +0, 46, 242, 243, 244, 245, + 246, 0, 0, 333, 335, 491, 559, 466, + 337, 417, 525, 527, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7885, 0, 0, 0, + 0, 0, 7887, +0, 46, 249, 250, 251, 361, 252, + 367, 0, 363, 365, 371, 0, 468, 369, + 432, 533, 535, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7909, 0, 7799, 7797, 0, + 7795, 7911, +0, 46, 7923, 253, 375, 7929, 255, 7833, + 0, 563, 0, 0, 7823, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7925, 0, 0, 0, 0, 0, + 7927, +6, 42, 7696, 0, 0, 0, 7690, 270, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7692, 7694, 7698, +6, 42, 7697, 0, + 0, 0, 7691, 271, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7693, 7695, 7699, +1, 11, 500, 284, 0, 0, 0, + 290, 7712, 286, 0, 288, 486, +1, 11, 501, 285, + 0, 0, 0, 291, 7713, 287, 0, 289, + 487, +2, 44, 292, 0, 7718, 0, 7720, 0, 0, + 0, 7714, 542, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7716, + 0, 0, 0, 7722, +2, 44, 293, 0, 7719, 0, + 7721, 0, 0, 0, 7715, 543, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7717, 7830, 0, 0, 7723, +2, 2, 308, +2, 11, + 309, 0, 0, 0, 0, 0, 0, 0, + 0, 496, +1, 41, 7728, 0, 0, 0, 0, 310, + 0, 0, 0, 0, 488, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7730, 7732, +1, 41, 7729, 0, 0, 0, 0, + 311, 0, 0, 0, 0, 489, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7731, 7733, +1, 42, 313, 0, 0, 0, + 0, 315, 0, 0, 0, 0, 317, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7734, 7738, 7740, +1, 42, 314, 0, + 0, 0, 0, 316, 0, 0, 0, 0, + 318, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7735, 7739, 7741, +1, 41, + 340, 0, 0, 0, 0, 342, 0, 0, + 0, 7768, 344, 0, 0, 528, 530, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7770, + 7774, +1, 41, 341, 0, 0, 0, 0, 343, 0, + 0, 0, 7769, 345, 0, 0, 529, 531, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7771, 7775, +1, 40, 346, 348, 0, 0, 0, 350, + 0, 0, 0, 7776, 352, 0, 0, 0, + 0, 536, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7778, +1, 40, 347, 349, 0, 0, 0, 351, + 0, 0, 0, 7777, 353, 0, 0, 0, + 0, 537, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7779, +6, 42, 354, 0, 0, 0, 7786, 356, + 0, 0, 0, 0, 538, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7788, 7790, 7792, +4, 42, 7831, + 0, 355, 0, 0, 0, 7787, 357, 0, + 0, 0, 0, 539, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7789, 7791, 7793, +0, 40, 7808, 7810, + 372, 0, 7812, 0, 0, 0, 0, 0, + 7814, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7816, +0, 40, 7809, + 7811, 373, 0, 7813, 7832, 0, 0, 0, + 0, 7815, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7817, +1, 41, + 377, 7824, 0, 0, 0, 0, 0, 0, + 0, 379, 381, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7826, + 7828, +1, 41, 378, 7825, 0, 0, 0, 0, 0, + 0, 0, 380, 382, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7827, 7829, +0, 11, 475, 471, 0, 0, 0, 0, + 0, 469, 0, 0, 0, 473, +0, 11, 476, 472, + 0, 0, 0, 0, 0, 470, 0, 0, + 0, 474, +7, 7, 478, +7, 7, 479, +7, 7, 480, +7, 7, 481, +1, 7, 508, 0, + 0, 0, 0, 0, 482, +1, 7, 509, 0, 0, + 0, 0, 0, 483, +7, 7, 492, +7, 7, 493, +11, 11, 494, +11, 11, 495, +1, 1, + 506, +1, 1, 507, +1, 1, 510, +1, 1, 511, +7, 7, 554, +7, 7, 555, +1, 7, 7756, 0, + 0, 7758, 0, 0, 556, +1, 7, 7757, 0, 0, + 7759, 0, 0, 557, +7, 7, 560, +7, 7, 561, +0, 49, 8173, 901, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8129, +0, 50, + 8122, 902, 0, 0, 0, 0, 0, 8121, + 8120, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7944, + 7945, 0, 8124, +0, 48, 8136, 904, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7960, 7961, +0, 50, 8138, 905, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7976, 7977, 0, 8140, +0, 48, 8154, + 906, 0, 0, 938, 0, 0, 8153, 8152, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7992, 7993, +0, 48, + 8184, 908, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8008, + 8009, +0, 48, 8170, 910, 0, 0, 939, 0, 0, + 8169, 8168, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8025, +0, 50, 8186, 911, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8040, 8041, 0, 8188, +0, 49, 8146, 912, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 8151, +0, 50, 8048, + 940, 0, 0, 0, 0, 0, 8113, 8112, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7936, 7937, + 8118, 8115, +0, 48, 8050, 941, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7952, 7953, +0, 50, 8052, 942, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7968, 7969, 8134, 8131, +0, 49, 8054, 943, + 0, 0, 970, 0, 0, 8145, 8144, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7984, 7985, 8150, +0, 49, + 8162, 944, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8167, +0, 49, 8058, 973, 0, 0, 971, 0, + 0, 8161, 8160, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8016, 8017, 8166, +0, 48, 8056, 972, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8000, 8001, +0, 50, 8060, 974, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8032, 8033, 8182, 8179, +1, 4, + 979, 0, 0, 980, +0, 8, 1024, 0, 0, 0, + 1025, 0, 0, 0, 1238, +1, 1, 1027, +4, 4, 1031, +1, 1, 1036, +0, 8, + 1037, 0, 0, 0, 1252, 0, 0, 1250, + 1049, +4, 12, 1264, 0, 0, 1262, 1038, 0, 0, + 0, 1266, +0, 8, 1117, 0, 0, 0, 1253, 0, + 0, 1251, 1081, +0, 8, 1104, 0, 0, 0, 1105, + 0, 0, 0, 1239, +1, 1, 1107, +4, 4, 1111, +1, 1, 1116, +4, 12, 1265, + 0, 0, 1263, 1118, 0, 0, 0, 1267, +14, 14, + 1142, +14, 14, 1143, +4, 8, 1244, 0, 0, 0, 1217, +4, 8, 1245, + 0, 0, 0, 1218, +4, 8, 1234, 0, 0, 0, + 1232, +4, 8, 1235, 0, 0, 0, 1233, +4, 4, 1242, +4, 4, 1243, +4, 4, + 1246, +4, 4, 1247, +4, 4, 1254, +4, 4, 1255, +4, 4, 1258, +4, 4, 1259, +4, 4, 1260, +4, 4, 1261, +4, 4, + 1268, +4, 4, 1269, +4, 4, 1272, +4, 4, 1273, +17, 19, 1570, 1571, 1573, +18, 18, 1572, +18, 18, + 1574, +18, 18, 1728, +18, 18, 1730, +18, 18, 1747, +20, 20, 2345, +20, 20, 2353, +20, 20, 2356, +21, 22, 2507, + 2508, +23, 25, 2888, 2891, 2892, +26, 26, 2964, +26, 27, 3020, 3018, +27, 27, 3019, +28, 28, + 3144, +29, 29, 3264, +29, 31, 3271, 3272, 3274, +29, 29, 3275, +32, 33, 3402, 3404, +32, 32, + 3403, +34, 36, 3546, 3548, 3550, +34, 34, 3549, +37, 37, 4134, +38, 38, 6918, +38, 38, 6920, +38, 38, + 6922, +38, 38, 6924, +38, 38, 6926, +38, 38, 6930, +38, 38, 6971, +38, 38, 6973, +38, 38, 6976, +38, 38, 6977, +38, 38, + 6979, +10, 41, 7682, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7684, + 7686, +10, 41, 7683, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7685, + 7687, +1, 1, 7688, +1, 1, 7689, +0, 1, 7700, 7702, +0, 1, 7701, 7703, +8, 8, 7708, +8, 8, + 7709, +10, 10, 7710, +10, 10, 7711, +1, 1, 7726, +1, 1, 7727, +7, 7, 7736, +7, 7, 7737, +1, 40, 7742, + 0, 0, 0, 0, 0, 0, 0, 0, + 7744, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7746, +1, 40, 7743, + 0, 0, 0, 0, 0, 0, 0, 0, + 7745, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7747, +0, 1, 7760, + 7762, +0, 1, 7761, 7763, +1, 10, 7764, 0, 0, 0, 0, + 0, 0, 0, 0, 7766, +1, 10, 7765, 0, 0, + 0, 0, 0, 0, 0, 0, 7767, +7, 7, 7772, +7, 7, + 7773, +10, 10, 7780, +10, 10, 7781, +10, 10, 7782, +10, 10, 7783, +10, 10, 7784, +10, 10, 7785, +1, 1, 7800, +1, 1, + 7801, +4, 4, 7802, +4, 4, 7803, +3, 40, 7804, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7806, +3, 40, 7805, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7807, +4, 10, 7820, + 0, 0, 0, 0, 0, 7818, +4, 10, 7821, 0, + 0, 0, 0, 0, 7819, +10, 10, 7835, +0, 46, 7846, 7844, + 0, 7850, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7848, +0, 46, 7847, 7845, 0, + 7851, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7849, +2, 8, 7852, 0, 0, 0, + 0, 0, 7862, +2, 8, 7853, 0, 0, 0, 0, + 0, 7863, +0, 46, 7856, 7854, 0, 7860, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7858, +0, 46, 7857, 7855, 0, 7861, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7859, +0, 46, + 7872, 7870, 0, 7876, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7874, +0, 46, 7873, + 7871, 0, 7877, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7875, +2, 2, 7878, +2, 2, 7879, +0, 46, + 7890, 7888, 0, 7894, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7892, +0, 46, 7891, + 7889, 0, 7895, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7893, +2, 2, 7896, +2, 2, 7897, +0, 46, + 7900, 7898, 0, 7904, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7906, 0, 0, 0, 0, 0, 7902, +0, 46, 7901, + 7899, 0, 7905, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7907, + 0, 0, 0, 0, 0, 7903, +0, 46, 7914, 7912, + 0, 7918, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7920, 0, + 0, 0, 0, 0, 7916, +0, 46, 7915, 7913, 0, + 7919, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7921, 0, 0, + 0, 0, 0, 7917, +0, 50, 7938, 7940, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7942, 8064, +0, 50, 7939, + 7941, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7943, 8065, +0, 50, 7946, 7948, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7950, 8072, +0, 50, 7947, 7949, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7951, 8073, +0, 1, + 7954, 7956, +0, 1, 7955, 7957, +0, 1, 7962, 7964, +0, 1, 7963, 7965, +0, 50, + 7970, 7972, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7974, 8080, +0, 50, 7971, 7973, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7975, 8081, +0, 50, 7978, 7980, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7982, + 8088, +0, 50, 7979, 7981, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7983, 8089, +0, 49, 7986, 7988, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7990, +0, 49, 7987, 7989, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7991, +0, 49, + 7994, 7996, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7998, +0, 49, 7995, 7997, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7999, +0, 1, 8002, 8004, +0, 1, 8003, 8005, +0, 1, + 8010, 8012, +0, 1, 8011, 8013, +0, 49, 8018, 8020, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8022, +0, 49, 8019, 8021, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8023, +0, 49, + 8027, 8029, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8031, +0, 50, 8034, 8036, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8038, 8096, +0, 50, 8035, 8037, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 8039, 8097, +0, 50, + 8042, 8044, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8046, 8104, +0, 50, 8043, 8045, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8047, 8105, +50, 50, 8066, +50, 50, 8067, +50, 50, + 8068, +50, 50, 8069, +50, 50, 8070, +50, 50, 8071, +50, 50, 8074, +50, 50, 8075, +50, 50, 8076, +50, 50, 8077, +50, 50, + 8078, +50, 50, 8079, +50, 50, 8082, +50, 50, 8083, +50, 50, 8084, +50, 50, 8085, +50, 50, 8086, +50, 50, 8087, +50, 50, + 8090, +50, 50, 8091, +50, 50, 8092, +50, 50, 8093, +50, 50, 8094, +50, 50, 8095, +50, 50, 8098, +50, 50, 8099, +50, 50, + 8100, +50, 50, 8101, +50, 50, 8102, +50, 50, 8103, +50, 50, 8106, +50, 50, 8107, +50, 50, 8108, +50, 50, 8109, +50, 50, + 8110, +50, 50, 8111, +50, 50, 8114, +50, 50, 8116, +50, 50, 8119, +50, 50, 8130, +50, 50, 8132, +50, 50, 8135, +0, 49, + 8141, 8142, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8143, +0, 49, 8157, 8158, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8159, +47, 48, 8164, 8165, +48, 48, 8172, +50, 50, 8178, +50, 50, + 8180, +50, 50, 8183, +51, 51, 8602, +51, 51, 8603, +51, 51, 8622, +51, 51, 8653, +51, 51, 8654, +51, 51, 8655, +51, 51, + 8708, +51, 51, 8713, +51, 51, 8716, +51, 51, 8740, +51, 51, 8742, +51, 51, 8769, +51, 51, 8772, +51, 51, 8775, +51, 51, + 8777, +51, 51, 8800, +51, 51, 8802, +51, 51, 8813, +51, 51, 8814, +51, 51, 8815, +51, 51, 8816, +51, 51, 8817, +51, 51, + 8820, +51, 51, 8821, +51, 51, 8824, +51, 51, 8825, +51, 51, 8832, +51, 51, 8833, +51, 51, 8836, +51, 51, 8837, +51, 51, + 8840, +51, 51, 8841, +51, 51, 8876, +51, 51, 8877, +51, 51, 8878, +51, 51, 8879, +51, 51, 8928, +51, 51, 8929, +51, 51, + 8930, +51, 51, 8931, +51, 51, 8938, +51, 51, 8939, +51, 51, 8940, +51, 51, 8941, +51, 51, 10972, +52, 52, 12364, +52, 52, + 12366, +52, 52, 12368, +52, 52, 12370, +52, 52, 12372, +52, 52, 12374, +52, 52, 12376, +52, 52, 12378, +52, 52, 12380, +52, 52, + 12382, +52, 52, 12384, +52, 52, 12386, +52, 52, 12389, +52, 52, 12391, +52, 52, 12393, +52, 53, 12400, 12401, +52, 53, + 12403, 12404, +52, 53, 12406, 12407, +52, 53, 12409, 12410, +52, 53, 12412, 12413, +52, 52, + 12436, +52, 52, 12446, +52, 52, 12460, +52, 52, 12462, +52, 52, 12464, +52, 52, 12466, +52, 52, 12468, +52, 52, 12470, +52, 52, + 12472, +52, 52, 12474, +52, 52, 12476, +52, 52, 12478, +52, 52, 12480, +52, 52, 12482, +52, 52, 12485, +52, 52, 12487, +52, 52, + 12489, +52, 53, 12496, 12497, +52, 53, 12499, 12500, +52, 53, 12502, 12503, +52, 53, 12505, + 12506, +52, 53, 12508, 12509, +52, 52, 12532, +52, 52, 12535, +52, 52, 12536, +52, 52, 12537, +52, 52, 12538, +52, 52, + 12542, +54, 55, 1, 4250, +54, 55, 1, 4252, +54, 55, 1, 4267, +56, 57, 1, 4398, +56, 57, 1, 4399, +58, 61, 1, 4939, 1, 4940, +62, 67, + 1, 5307, 1, 5308, 1, 5310, +68, 69, 1, 5562, +68, 69, 1, 5563, +70, 71, 1, 6456, +72, 73, 1, 53598, +72, 73, 1, 53599, +74, 83, + 1, 53600, 1, 53601, 1, 53602, 1, 53603, 1, 53604, +72, 73, 1, 53691, +72, 73, 1, 53692, +74, 77, 1, 53693, + 1, 53695, +74, 77, 1, 53694, 1, 53696, +}; +