diff --git a/Makefile b/Makefile index 696a742..108ce5c 100644 --- a/Makefile +++ b/Makefile @@ -155,6 +155,7 @@ endif ifdef CONFIG_UNICODE_JOIN OBJS+= unicode_join.o arabic.o indic.o + OBJS+= libunicode.o libregexp.o endif # more charsets if needed @@ -339,6 +340,8 @@ $(OBJS_DIR)/charsetjis.o: charsetjis.c charsetjis.def $(OBJS_DIR)/fbfrender.o: fbfrender.c fbfrender.h libfbf.h $(OBJS_DIR)/qe.o: qe.c qeconfig.h $(OBJS_DIR)/modes/stb.o: modes/stb.c modes/stb_image.h +$(OBJS_DIR)/libunicode.o: libunicode.c libunicode.h libunicode-table.h +$(OBJS_DIR)/libregexp.o: libregexp.c libregexp.h libregexp-opcode.h $(OBJS_DIR)/%.o: %.c $(DEPENDS) Makefile $(echo) CC $(ECHO_CFLAGS) -c $< @@ -471,6 +474,10 @@ unitable.txt: $(BINDIR)/unitable$(EXE) Makefile unicode_width: $(BINDIR)/unitable$(EXE) Makefile $(BINDIR)/unitable -V $(UNICODE_VER) -W -a > unicode_width.h +# +#libunicode_table: $(BINDIR)/unicode_gen$(EXE) Makefile +# $(BINDIR)/unicode_gen libunicode-table.h + # # fonts (only needed for html2png) # diff --git a/TODO.md b/TODO.md index 13e7482..9fd3bad 100644 --- a/TODO.md +++ b/TODO.md @@ -313,7 +313,7 @@ insert_window_left() deletes some left-most windows * `hex-mode` search strings should mix hex ut8 strings and ASCII control char names * isearch in hex should display search string in hex * transfer case in `query-replace` -* regex search/replace +* regex replace with subexpressions * query replace across multiple files * query replace options: u -> undo last change * add non selectable query-replace-mode for key bindings, cmd description and documentation diff --git a/VERSION b/VERSION index 09b254e..dfda3e0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.0.0 +6.1.0 diff --git a/cutils.c b/cutils.c index 0de0932..0ddd3df 100644 --- a/cutils.c +++ b/cutils.c @@ -23,6 +23,7 @@ * THE SOFTWARE. */ +#include #include #include "config.h" /* for CONFIG_WIN32 */ @@ -236,3 +237,244 @@ char *get_dirname(char *dest, int size, const char *file) { } return dest; } + +/* Dynamic buffer package */ + +static void *dbuf_default_realloc(void *opaque, void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func) +{ + memset(s, 0, sizeof(*s)); + if (!realloc_func) + realloc_func = dbuf_default_realloc; + s->opaque = opaque; + s->realloc_func = realloc_func; +} + +void dbuf_init(DynBuf *s) +{ + dbuf_init2(s, NULL, NULL); +} + +/* return < 0 if error */ +int dbuf_realloc(DynBuf *s, size_t new_size) +{ + size_t size = s->allocated_size; + if (new_size > size) { + uint8_t *new_buf; + if (s->error) + return -1; + size += size / 2; + if (new_size < size) + new_size = size; + new_buf = s->realloc_func(s->opaque, s->buf, new_size); + if (!new_buf) { + s->error = TRUE; + return -1; + } + s->buf = new_buf; + s->allocated_size = new_size; + } + return 0; +} + +int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len) +{ + size_t end; + end = offset + len; + if (dbuf_realloc(s, end)) + return -1; + memcpy(s->buf + offset, data, len); + if (end > s->size) + s->size = end; + return 0; +} + +int dbuf_put(DynBuf *s, const uint8_t *data, size_t len) +{ + if (unlikely((s->size + len) > s->allocated_size)) { + if (dbuf_realloc(s, s->size + len)) + return -1; + } + memcpy(s->buf + s->size, data, len); + s->size += len; + return 0; +} + +int dbuf_put_self(DynBuf *s, size_t offset, size_t len) +{ + if (unlikely((s->size + len) > s->allocated_size)) { + if (dbuf_realloc(s, s->size + len)) + return -1; + } + memcpy(s->buf + s->size, s->buf + offset, len); + s->size += len; + return 0; +} + +int dbuf_putc(DynBuf *s, uint8_t c) +{ + return dbuf_put(s, &c, 1); +} + +int dbuf_putstr(DynBuf *s, const char *str) +{ + return dbuf_put(s, (const uint8_t *)str, strlen(str)); +} + +int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s, + const char *fmt, ...) +{ + va_list ap; + char buf[128]; + int len; + + va_start(ap, fmt); + len = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + if (len < 0) + return len; + if (len < (int)sizeof(buf)) { + /* fast case */ + return dbuf_put(s, (uint8_t *)buf, len); + } else { + if (dbuf_realloc(s, s->size + len + 1)) + return -1; + va_start(ap, fmt); + vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size, + fmt, ap); + va_end(ap); + s->size += len; + } + return 0; +} + +void dbuf_free(DynBuf *s) +{ + /* we test s->buf as a fail safe to avoid crashing if dbuf_free() + is called twice */ + if (s->buf) { + s->realloc_func(s->opaque, s->buf, 0); + } + memset(s, 0, sizeof(*s)); +} + +/* Note: at most 31 bits are encoded. At most UTF8_CHAR_LEN_MAX bytes + are output. */ +int unicode_to_utf8(uint8_t *buf, unsigned int c) +{ + uint8_t *q = buf; + + if (c < 0x80) { + *q++ = c; + } else { + if (c < 0x800) { + *q++ = (c >> 6) | 0xc0; + } else { + if (c < 0x10000) { + *q++ = (c >> 12) | 0xe0; + } else { + if (c < 0x00200000) { + *q++ = (c >> 18) | 0xf0; + } else { + if (c < 0x04000000) { + *q++ = (c >> 24) | 0xf8; + } else if (c < 0x80000000) { + *q++ = (c >> 30) | 0xfc; + *q++ = ((c >> 24) & 0x3f) | 0x80; + } else { + return 0; + } + *q++ = ((c >> 18) & 0x3f) | 0x80; + } + *q++ = ((c >> 12) & 0x3f) | 0x80; + } + *q++ = ((c >> 6) & 0x3f) | 0x80; + } + *q++ = (c & 0x3f) | 0x80; + } + return q - buf; +} + +#if 0 +static const int utf8_min_code[5] = { + 0x80, 0x800, 0x10000, 0x200000, 0x4000000, + //0x80, 0x20, 0x400, 0x8000, 0x100000, + //0x80, 0x20, 0x10, 0x200, 0x4000, + //0x80, 0x20, 0x10, 0x8, 0x100, + //0x80, 0x20, 0x10, 0x8, 0x4, +}; +#endif + +/* return -1 if error. *pp is not updated in this case. max_len must + be >= 1. The maximum length for a UTF-8 byte sequence is 6 bytes. */ +// XXX: should return synthetic byte code for invalid UTF-8 encoding +// emacs uses 0x3fff80-0x3fffff for invalud bytes 0x80 to 0xff. +int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp) +{ + int c, n, b; + + c = *p++; + if (c < 0x80) { + *pp = p; + return c; + } + switch (c) { + case 0xc0: case 0xc1: + return -1; + case 0xc2: case 0xc3: + case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: + case 0xcc: case 0xcd: case 0xce: case 0xcf: + case 0xd0: case 0xd1: case 0xd2: case 0xd3: + case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: + case 0xdc: case 0xdd: case 0xde: case 0xdf: + if (max_len < 2) + return -1; + b = *p++ ^ 0x80; + if (b >= 0x40) + return -1; + c = ((c & 0x1f) << 6) | b; + *pp = p; + return c; + case 0xe0: case 0xe1: case 0xe2: case 0xe3: + case 0xe4: case 0xe5: case 0xe6: case 0xe7: + case 0xe8: case 0xe9: case 0xea: case 0xeb: + case 0xec: case 0xed: case 0xee: case 0xef: + n = 1; + break; + case 0xf0: case 0xf1: case 0xf2: case 0xf3: + case 0xf4: case 0xf5: case 0xf6: case 0xf7: + n = 2; + break; + case 0xf8: case 0xf9: case 0xfa: case 0xfb: + n = 3; + break; + case 0xfc: case 0xfd: + n = 4; + break; + default: + return -1; + } + if (max_len < n + 2) + return -1; + b = *p++ ^ 0x80; + if (b >= 0x40) + return -1; + c &= 0x1f >> n; + c = (c << 6) | b; + if (c < (0x40 >> n)) + return -1; + while (n --> 0) { + b = *p++ ^ 0x80; + if (b >= 0x40) + return -1; + c = (c << 6) | b; + } + *pp = p; + return c; +} diff --git a/cutils.h b/cutils.h index 31e3f34..7c8414b 100644 --- a/cutils.h +++ b/cutils.h @@ -270,6 +270,208 @@ static inline int min_uint(unsigned int a, unsigned int b) { return b; } +static inline uint32_t max_uint32(uint32_t a, uint32_t b) { + if (a > b) + return a; + else + return b; +} + +static inline uint32_t min_uint32(uint32_t a, uint32_t b) { + if (a < b) + return a; + else + return b; +} + +static inline int64_t max_int64(int64_t a, int64_t b) { + if (a > b) + return a; + else + return b; +} + +static inline int64_t min_int64(int64_t a, int64_t b) { + if (a < b) + return a; + else + return b; +} + +/* WARNING: undefined if a = 0 */ +static inline int clz32(unsigned int a) +{ + return __builtin_clz(a); +} + +/* WARNING: undefined if a = 0 */ +static inline int clz64(uint64_t a) +{ + return __builtin_clzll(a); +} + +/* WARNING: undefined if a = 0 */ +static inline int ctz32(unsigned int a) +{ + return __builtin_ctz(a); +} + +/* WARNING: undefined if a = 0 */ +static inline int ctz64(uint64_t a) +{ + return __builtin_ctzll(a); +} + +struct __attribute__((packed)) packed_u64 { + uint64_t v; +}; + +struct __attribute__((packed)) packed_u32 { + uint32_t v; +}; + +struct __attribute__((packed)) packed_u16 { + uint16_t v; +}; + +static inline uint64_t get_u64(const uint8_t *tab) +{ + return ((const struct packed_u64 *)tab)->v; +} + +static inline int64_t get_i64(const uint8_t *tab) +{ + return (int64_t)((const struct packed_u64 *)tab)->v; +} + +static inline void put_u64(uint8_t *tab, uint64_t val) +{ + ((struct packed_u64 *)tab)->v = val; +} + +static inline uint32_t get_u32(const uint8_t *tab) +{ + return ((const struct packed_u32 *)tab)->v; +} + +static inline int32_t get_i32(const uint8_t *tab) +{ + return (int32_t)((const struct packed_u32 *)tab)->v; +} + +static inline void put_u32(uint8_t *tab, uint32_t val) +{ + ((struct packed_u32 *)tab)->v = val; +} + +static inline uint32_t get_u16(const uint8_t *tab) +{ + return ((const struct packed_u16 *)tab)->v; +} + +static inline int32_t get_i16(const uint8_t *tab) +{ + return (int16_t)((const struct packed_u16 *)tab)->v; +} + +static inline void put_u16(uint8_t *tab, uint16_t val) +{ + ((struct packed_u16 *)tab)->v = val; +} + +static inline uint32_t get_u8(const uint8_t *tab) +{ + return *tab; +} + +static inline int32_t get_i8(const uint8_t *tab) +{ + return (int8_t)*tab; +} + +static inline void put_u8(uint8_t *tab, uint8_t val) +{ + *tab = val; +} + +static inline uint16_t bswap16(uint16_t x) +{ + return (x >> 8) | (x << 8); +} + +static inline uint32_t bswap32(uint32_t v) +{ + return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) | + ((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24); +} + +static inline uint64_t bswap64(uint64_t v) +{ + return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) | + ((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) | + ((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) | + ((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) | + ((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) | + ((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) | + ((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) | + ((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8)); +} + +/* XXX: should take an extra argument to pass slack information to the caller */ +typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size); + +typedef struct DynBuf { + uint8_t *buf; + size_t size; + size_t allocated_size; + BOOL error; /* true if a memory allocation error occurred */ + DynBufReallocFunc *realloc_func; + void *opaque; /* for realloc_func */ +} DynBuf; + +void dbuf_init(DynBuf *s); +void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func); +int dbuf_realloc(DynBuf *s, size_t new_size); +int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len); +int dbuf_put(DynBuf *s, const uint8_t *data, size_t len); +int dbuf_put_self(DynBuf *s, size_t offset, size_t len); +int dbuf_putc(DynBuf *s, uint8_t c); +int dbuf_putstr(DynBuf *s, const char *str); +static inline int dbuf_put_u16(DynBuf *s, uint16_t val) { + return dbuf_put(s, (uint8_t *)&val, 2); +} +static inline int dbuf_put_u32(DynBuf *s, uint32_t val) { + return dbuf_put(s, (uint8_t *)&val, 4); +} +static inline int dbuf_put_u64(DynBuf *s, uint64_t val) { + return dbuf_put(s, (uint8_t *)&val, 8); +} +int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s, + const char *fmt, ...); +void dbuf_free(DynBuf *s); +static inline BOOL dbuf_error(DynBuf *s) { + return s->error; +} +static inline void dbuf_set_error(DynBuf *s) { + s->error = TRUE; +} + +#define UTF8_CHAR_LEN_MAX 6 + +int unicode_to_utf8(uint8_t *buf, unsigned int c); +int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp); + +static inline int from_hex(int c) { + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else + return -1; +} + /* Double linked lists. Same API as the linux kernel */ struct list_head { diff --git a/libregexp-opcode.h b/libregexp-opcode.h new file mode 100644 index 0000000..cd3683f --- /dev/null +++ b/libregexp-opcode.h @@ -0,0 +1,58 @@ +/* + * Regular Expression Engine + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * 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. + */ + +#ifdef DEF + +DEF(invalid, 1) /* never used */ +DEF(char, 3) +DEF(char32, 5) +DEF(dot, 1) +DEF(any, 1) /* same as dot but match any character including line terminator */ +DEF(line_start, 1) +DEF(line_end, 1) +DEF(goto, 5) +DEF(split_goto_first, 5) +DEF(split_next_first, 5) +DEF(match, 1) +DEF(save_start, 2) /* save start position */ +DEF(save_end, 2) /* save end position, must come after saved_start */ +DEF(save_reset, 3) /* reset save positions */ +DEF(loop, 5) /* decrement the top the stack and goto if != 0 */ +DEF(push_i32, 5) /* push integer on the stack */ +DEF(drop, 1) +DEF(word_boundary, 1) +DEF(not_word_boundary, 1) +DEF(back_reference, 2) +DEF(backward_back_reference, 2) /* must come after back_reference */ +DEF(range, 3) /* variable length */ +DEF(range32, 3) /* variable length */ +DEF(lookahead, 5) +DEF(negative_lookahead, 5) +DEF(push_char_pos, 1) /* push the character position on the stack */ +DEF(bne_char_pos, 5) /* pop one stack element and jump if equal to the character + position */ +DEF(prev, 1) /* go to the previous char */ +DEF(simple_greedy_quant, 17) + +#endif /* DEF */ diff --git a/libregexp.c b/libregexp.c new file mode 100644 index 0000000..5e47e4a --- /dev/null +++ b/libregexp.c @@ -0,0 +1,2680 @@ +/* + * Regular Expression Engine + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * 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. + */ +#include +#include +#include +#include +#include +#include + +#include "cutils.h" +#include "libregexp.h" + +/* + TODO: + + - Add full unicode canonicalize rules for character ranges (not + really useful but needed for exact "ignorecase" compatibility). + + - Add a lock step execution mode (=linear time execution guaranteed) + when the regular expression is "simple" i.e. no backreference nor + complicated lookahead. The opcodes are designed for this execution + model. +*/ + +#if defined(TEST) +#define DUMP_REOP +#endif + +typedef enum { +#define DEF(id, size) REOP_ ## id, +#include "libregexp-opcode.h" +#undef DEF + REOP_COUNT, +} REOPCodeEnum; + +#define CAPTURE_COUNT_MAX 255 +#define STACK_SIZE_MAX 255 + +/* unicode code points */ +#define CP_LS 0x2028 +#define CP_PS 0x2029 + +#define TMP_BUF_SIZE 128 + +typedef struct { + DynBuf byte_code; + const uint8_t *buf_ptr; + const uint8_t *buf_end; + const uint8_t *buf_start; + int re_flags; + BOOL is_utf16; + BOOL ignore_case; + BOOL dotall; + int capture_count; + int total_capture_count; /* -1 = not computed yet */ + int has_named_captures; /* -1 = don't know, 0 = no, 1 = yes */ + void *opaque; + DynBuf group_names; + union { + char error_msg[TMP_BUF_SIZE]; + char tmp_buf[TMP_BUF_SIZE]; + } u; +} REParseState; + +typedef struct { +#ifdef DUMP_REOP + const char *name; +#endif + uint8_t size; +} REOpCode; + +static const REOpCode reopcode_info[REOP_COUNT] = { +#ifdef DUMP_REOP +#define DEF(id, size) { #id, size }, +#else +#define DEF(id, size) { size }, +#endif +#include "libregexp-opcode.h" +#undef DEF +}; + +#define RE_HEADER_FLAGS 0 +#define RE_HEADER_CAPTURE_COUNT 1 +#define RE_HEADER_STACK_SIZE 2 + +#define RE_HEADER_LEN 7 + +static inline int is_digit(int c) { + return c >= '0' && c <= '9'; +} + +/* insert 'len' bytes at position 'pos'. Return < 0 if error. */ +static int dbuf_insert(DynBuf *s, int pos, int len) +{ + if (dbuf_realloc(s, s->size + len)) + return -1; + memmove(s->buf + pos + len, s->buf + pos, s->size - pos); + s->size += len; + return 0; +} + +/* canonicalize with the specific JS regexp rules */ +static uint32_t lre_canonicalize(uint32_t c, BOOL is_utf16) +{ + uint32_t res[LRE_CC_RES_LEN_MAX]; + int len; + if (is_utf16) { + if (likely(c < 128)) { + if (c >= 'A' && c <= 'Z') + c = c - 'A' + 'a'; + } else { + lre_case_conv(res, c, 2); + c = res[0]; + } + } else { + if (likely(c < 128)) { + if (c >= 'a' && c <= 'z') + c = c - 'a' + 'A'; + } else { + /* legacy regexp: to upper case if single char >= 128 */ + len = lre_case_conv(res, c, FALSE); + if (len == 1 && res[0] >= 128) + c = res[0]; + } + } + return c; +} + +static const uint16_t char_range_d[] = { + 1, + 0x0030, 0x0039 + 1, +}; + +/* code point ranges for Zs,Zl or Zp property */ +static const uint16_t char_range_s[] = { + 10, + 0x0009, 0x000D + 1, + 0x0020, 0x0020 + 1, + 0x00A0, 0x00A0 + 1, + 0x1680, 0x1680 + 1, + 0x2000, 0x200A + 1, + /* 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; */ + /* 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; */ + 0x2028, 0x2029 + 1, + 0x202F, 0x202F + 1, + 0x205F, 0x205F + 1, + 0x3000, 0x3000 + 1, + /* FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; */ + 0xFEFF, 0xFEFF + 1, +}; + +BOOL lre_is_space(int c) +{ + int i, n, low, high; + n = (countof(char_range_s) - 1) / 2; + for(i = 0; i < n; i++) { + low = char_range_s[2 * i + 1]; + if (c < low) + return FALSE; + high = char_range_s[2 * i + 2]; + if (c < high) + return TRUE; + } + return FALSE; +} + +uint32_t const lre_id_start_table_ascii[4] = { + /* $ A-Z _ a-z */ + 0x00000000, 0x00000010, 0x87FFFFFE, 0x07FFFFFE +}; + +uint32_t const lre_id_continue_table_ascii[4] = { + /* $ 0-9 A-Z _ a-z */ + 0x00000000, 0x03FF0010, 0x87FFFFFE, 0x07FFFFFE +}; + + +static const uint16_t char_range_w[] = { + 4, + 0x0030, 0x0039 + 1, + 0x0041, 0x005A + 1, + 0x005F, 0x005F + 1, + 0x0061, 0x007A + 1, +}; + +#define CLASS_RANGE_BASE 0x40000000 + +typedef enum { + CHAR_RANGE_d, + CHAR_RANGE_D, + CHAR_RANGE_s, + CHAR_RANGE_S, + CHAR_RANGE_w, + CHAR_RANGE_W, +} CharRangeEnum; + +static const uint16_t *char_range_table[] = { + char_range_d, + char_range_s, + char_range_w, +}; + +static int cr_init_char_range(REParseState *s, CharRange *cr, uint32_t c) +{ + BOOL invert; + const uint16_t *c_pt; + int len, i; + + invert = c & 1; + c_pt = char_range_table[c >> 1]; + len = *c_pt++; + cr_init(cr, s->opaque, lre_realloc); + for(i = 0; i < len * 2; i++) { + if (cr_add_point(cr, c_pt[i])) + goto fail; + } + if (invert) { + if (cr_invert(cr)) + goto fail; + } + return 0; + fail: + cr_free(cr); + return -1; +} + +static int cr_canonicalize(CharRange *cr) +{ + CharRange a; + uint32_t pt[2]; + int i, ret; + + cr_init(&a, cr->mem_opaque, lre_realloc); + pt[0] = 'a'; + pt[1] = 'z' + 1; + ret = cr_op(&a, cr->points, cr->len, pt, 2, CR_OP_INTER); + if (ret) + goto fail; + /* convert to upper case */ + /* XXX: the generic unicode case would be much more complicated + and not really useful */ + for(i = 0; i < a.len; i++) { + a.points[i] += 'A' - 'a'; + } + /* Note: for simplicity we keep the lower case ranges */ + ret = cr_union1(cr, a.points, a.len); + fail: + cr_free(&a); + return ret; +} + +#ifdef DUMP_REOP +static __maybe_unused void lre_dump_bytecode(const uint8_t *buf, + int buf_len) +{ + int pos, len, opcode, bc_len, re_flags, i; + uint32_t val; + + assert(buf_len >= RE_HEADER_LEN); + + re_flags= buf[0]; + bc_len = get_u32(buf + 3); + assert(bc_len + RE_HEADER_LEN <= buf_len); + printf("flags: 0x%x capture_count=%d stack_size=%d\n", + re_flags, buf[1], buf[2]); + if (re_flags & LRE_FLAG_NAMED_GROUPS) { + const char *p; + p = (char *)buf + RE_HEADER_LEN + bc_len; + printf("named groups: "); + for(i = 1; i < buf[1]; i++) { + if (i != 1) + printf(","); + printf("<%s>", p); + p += strlen(p) + 1; + } + printf("\n"); + assert(p == (char *)(buf + buf_len)); + } + printf("bytecode_len=%d\n", bc_len); + + buf += RE_HEADER_LEN; + pos = 0; + while (pos < bc_len) { + printf("%5u: ", pos); + opcode = buf[pos]; + len = reopcode_info[opcode].size; + if (opcode >= REOP_COUNT) { + printf(" invalid opcode=0x%02x\n", opcode); + break; + } + if ((pos + len) > bc_len) { + printf(" buffer overflow (opcode=0x%02x)\n", opcode); + break; + } + printf("%s", reopcode_info[opcode].name); + switch(opcode) { + case REOP_char: + val = get_u16(buf + pos + 1); + if (val >= ' ' && val <= 126) + printf(" '%c'", val); + else + printf(" 0x%04x", val); + break; + case REOP_char32: + val = get_u32(buf + pos + 1); + if (val >= ' ' && val <= 126) + printf(" '%c'", val); + else + printf(" 0x%08x", val); + break; + case REOP_goto: + case REOP_split_goto_first: + case REOP_split_next_first: + case REOP_loop: + case REOP_lookahead: + case REOP_negative_lookahead: + case REOP_bne_char_pos: + val = get_u32(buf + pos + 1); + val += (pos + 5); + printf(" %u", val); + break; + case REOP_simple_greedy_quant: + printf(" %u %u %u %u", + get_u32(buf + pos + 1) + (pos + 17), + get_u32(buf + pos + 1 + 4), + get_u32(buf + pos + 1 + 8), + get_u32(buf + pos + 1 + 12)); + break; + case REOP_save_start: + case REOP_save_end: + case REOP_back_reference: + case REOP_backward_back_reference: + printf(" %u", buf[pos + 1]); + break; + case REOP_save_reset: + printf(" %u %u", buf[pos + 1], buf[pos + 2]); + break; + case REOP_push_i32: + val = get_u32(buf + pos + 1); + printf(" %d", val); + break; + case REOP_range: + { + int n, i; + n = get_u16(buf + pos + 1); + len += n * 4; + for(i = 0; i < n * 2; i++) { + val = get_u16(buf + pos + 3 + i * 2); + printf(" 0x%04x", val); + } + } + break; + case REOP_range32: + { + int n, i; + n = get_u16(buf + pos + 1); + len += n * 8; + for(i = 0; i < n * 2; i++) { + val = get_u32(buf + pos + 3 + i * 4); + printf(" 0x%08x", val); + } + } + break; + default: + break; + } + printf("\n"); + pos += len; + } +} +#endif + +static void re_emit_op(REParseState *s, int op) +{ + dbuf_putc(&s->byte_code, op); +} + +/* return the offset of the u32 value */ +static int re_emit_op_u32(REParseState *s, int op, uint32_t val) +{ + int pos; + dbuf_putc(&s->byte_code, op); + pos = s->byte_code.size; + dbuf_put_u32(&s->byte_code, val); + return pos; +} + +static int re_emit_goto(REParseState *s, int op, uint32_t val) +{ + int pos; + dbuf_putc(&s->byte_code, op); + pos = s->byte_code.size; + dbuf_put_u32(&s->byte_code, val - (pos + 4)); + return pos; +} + +static void re_emit_op_u8(REParseState *s, int op, uint32_t val) +{ + dbuf_putc(&s->byte_code, op); + dbuf_putc(&s->byte_code, val); +} + +static void re_emit_op_u16(REParseState *s, int op, uint32_t val) +{ + dbuf_putc(&s->byte_code, op); + dbuf_put_u16(&s->byte_code, val); +} + +static int __attribute__((format(printf, 2, 3))) re_parse_error(REParseState *s, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vsnprintf(s->u.error_msg, sizeof(s->u.error_msg), fmt, ap); + va_end(ap); + return -1; +} + +static int re_parse_out_of_memory(REParseState *s) +{ + return re_parse_error(s, "out of memory"); +} + +/* If allow_overflow is false, return -1 in case of + overflow. Otherwise return INT32_MAX. */ +static int parse_digits(const uint8_t **pp, BOOL allow_overflow) +{ + const uint8_t *p; + uint64_t v; + int c; + + p = *pp; + v = 0; + for(;;) { + c = *p; + if (c < '0' || c > '9') + break; + v = v * 10 + c - '0'; + if (v >= INT32_MAX) { + if (allow_overflow) + v = INT32_MAX; + else + return -1; + } + p++; + } + *pp = p; + return v; +} + +static int re_parse_expect(REParseState *s, const uint8_t **pp, int c) +{ + const uint8_t *p; + p = *pp; + if (*p != c) + return re_parse_error(s, "expecting '%c'", c); + p++; + *pp = p; + return 0; +} + +/* Parse an escape sequence, *pp points after the '\': + allow_utf16 value: + 0 : no UTF-16 escapes allowed + 1 : UTF-16 escapes allowed + 2 : UTF-16 escapes allowed and escapes of surrogate pairs are + converted to a unicode character (unicode regexp case). + + Return the unicode char and update *pp if recognized, + return -1 if malformed escape, + return -2 otherwise. */ +int lre_parse_escape(const uint8_t **pp, int allow_utf16) +{ + const uint8_t *p; + uint32_t c; + + p = *pp; + c = *p++; + switch(c) { + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + case 'x': + case 'u': + { + int h, n, i; + uint32_t c1; + + if (*p == '{' && allow_utf16) { + p++; + c = 0; + for(;;) { + h = from_hex(*p++); + if (h < 0) + return -1; + c = (c << 4) | h; + if (c > 0x10FFFF) + return -1; + if (*p == '}') + break; + } + p++; + } else { + if (c == 'x') { + n = 2; + } else { + n = 4; + } + + c = 0; + for(i = 0; i < n; i++) { + h = from_hex(*p++); + if (h < 0) { + return -1; + } + c = (c << 4) | h; + } + if (c >= 0xd800 && c < 0xdc00 && + allow_utf16 == 2 && p[0] == '\\' && p[1] == 'u') { + /* convert an escaped surrogate pair into a + unicode char */ + c1 = 0; + for(i = 0; i < 4; i++) { + h = from_hex(p[2 + i]); + if (h < 0) + break; + c1 = (c1 << 4) | h; + } + if (i == 4 && c1 >= 0xdc00 && c1 < 0xe000) { + p += 6; + c = (((c & 0x3ff) << 10) | (c1 & 0x3ff)) + 0x10000; + } + } + } + } + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c -= '0'; + if (allow_utf16 == 2) { + /* only accept \0 not followed by digit */ + if (c != 0 || is_digit(*p)) + return -1; + } else { + /* parse a legacy octal sequence */ + uint32_t v; + v = *p - '0'; + if (v > 7) + break; + c = (c << 3) | v; + p++; + if (c >= 32) + break; + v = *p - '0'; + if (v > 7) + break; + c = (c << 3) | v; + p++; + } + break; + default: + return -2; + } + *pp = p; + return c; +} + +#ifdef CONFIG_ALL_UNICODE +/* XXX: we use the same chars for name and value */ +static BOOL is_unicode_char(int c) +{ + return ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c == '_')); +} + +static int parse_unicode_property(REParseState *s, CharRange *cr, + const uint8_t **pp, BOOL is_inv) +{ + const uint8_t *p; + char name[64], value[64]; + char *q; + BOOL script_ext; + int ret; + + p = *pp; + if (*p != '{') + return re_parse_error(s, "expecting '{' after \\p"); + p++; + q = name; + while (is_unicode_char(*p)) { + if ((size_t)(q - name + 1) >= sizeof(name)) + goto unknown_property_name; + *q++ = *p++; + } + *q = '\0'; + q = value; + if (*p == '=') { + p++; + while (is_unicode_char(*p)) { + if ((size_t)(q - value + 1) >= sizeof(value)) + return re_parse_error(s, "unknown unicode property value"); + *q++ = *p++; + } + } + *q = '\0'; + if (*p != '}') + return re_parse_error(s, "expecting '}'"); + p++; + // printf("name=%s value=%s\n", name, value); + + if (!strcmp(name, "Script") || !strcmp(name, "sc")) { + script_ext = FALSE; + goto do_script; + } else if (!strcmp(name, "Script_Extensions") || !strcmp(name, "scx")) { + script_ext = TRUE; + do_script: + cr_init(cr, s->opaque, lre_realloc); + ret = unicode_script(cr, value, script_ext); + if (ret) { + cr_free(cr); + if (ret == -2) + return re_parse_error(s, "unknown unicode script"); + else + goto out_of_memory; + } + } else if (!strcmp(name, "General_Category") || !strcmp(name, "gc")) { + cr_init(cr, s->opaque, lre_realloc); + ret = unicode_general_category(cr, value); + if (ret) { + cr_free(cr); + if (ret == -2) + return re_parse_error(s, "unknown unicode general category"); + else + goto out_of_memory; + } + } else if (value[0] == '\0') { + cr_init(cr, s->opaque, lre_realloc); + ret = unicode_general_category(cr, name); + if (ret == -1) { + cr_free(cr); + goto out_of_memory; + } + if (ret < 0) { + ret = unicode_prop(cr, name); + if (ret) { + cr_free(cr); + if (ret == -2) + goto unknown_property_name; + else + goto out_of_memory; + } + } + } else { + unknown_property_name: + return re_parse_error(s, "unknown unicode property name"); + } + + if (is_inv) { + if (cr_invert(cr)) { + cr_free(cr); + return -1; + } + } + *pp = p; + return 0; + out_of_memory: + return re_parse_out_of_memory(s); +} +#endif /* CONFIG_ALL_UNICODE */ + +/* return -1 if error otherwise the character or a class range + (CLASS_RANGE_BASE). In case of class range, 'cr' is + initialized. Otherwise, it is ignored. */ +static int get_class_atom(REParseState *s, CharRange *cr, + const uint8_t **pp, BOOL inclass) +{ + const uint8_t *p; + uint32_t c; + int ret; + + p = *pp; + + c = *p; + switch(c) { + case '\\': + p++; + if (p >= s->buf_end) + goto unexpected_end; + c = *p++; + switch(c) { + case 'd': + c = CHAR_RANGE_d; + goto class_range; + case 'D': + c = CHAR_RANGE_D; + goto class_range; + case 's': + c = CHAR_RANGE_s; + goto class_range; + case 'S': + c = CHAR_RANGE_S; + goto class_range; + case 'w': + c = CHAR_RANGE_w; + goto class_range; + case 'W': + c = CHAR_RANGE_W; + class_range: + if (cr_init_char_range(s, cr, c)) + return -1; + c = CLASS_RANGE_BASE; + break; + case 'c': + c = *p; + if ((c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (((c >= '0' && c <= '9') || c == '_') && + inclass && !s->is_utf16)) { /* Annex B.1.4 */ + c &= 0x1f; + p++; + } else if (s->is_utf16) { + goto invalid_escape; + } else { + /* otherwise return '\' and 'c' */ + p--; + c = '\\'; + } + break; +#ifdef CONFIG_ALL_UNICODE + case 'p': + case 'P': + if (s->is_utf16) { + if (parse_unicode_property(s, cr, &p, (c == 'P'))) + return -1; + c = CLASS_RANGE_BASE; + break; + } + /* fall thru */ +#endif + default: + p--; + ret = lre_parse_escape(&p, s->is_utf16 * 2); + if (ret >= 0) { + c = ret; + } else { + if (ret == -2 && *p != '\0' && strchr("^$\\.*+?()[]{}|/", *p)) { + /* always valid to escape these characters */ + goto normal_char; + } else if (s->is_utf16) { + invalid_escape: + return re_parse_error(s, "invalid escape sequence in regular expression"); + } else { + /* just ignore the '\' */ + goto normal_char; + } + } + break; + } + break; + case '\0': + if (p >= s->buf_end) { + unexpected_end: + return re_parse_error(s, "unexpected end"); + } + /* fall thru */ + default: + normal_char: + /* normal char */ + if (c >= 128) { + c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); + if ((unsigned)c > 0xffff && !s->is_utf16) { + /* XXX: should handle non BMP-1 code points */ + return re_parse_error(s, "malformed unicode char"); + } + } else { + p++; + } + break; + } + *pp = p; + return c; +} + +static int re_emit_range(REParseState *s, const CharRange *cr) +{ + int len, i; + uint32_t high; + + len = (unsigned)cr->len / 2; + if (len >= 65535) + return re_parse_error(s, "too many ranges"); + if (len == 0) { + /* not sure it can really happen. Emit a match that is always + false */ + re_emit_op_u32(s, REOP_char32, -1); + } else { + high = cr->points[cr->len - 1]; + if (high == UINT32_MAX) + high = cr->points[cr->len - 2]; + if (high <= 0xffff) { + /* can use 16 bit ranges with the conversion that 0xffff = + infinity */ + re_emit_op_u16(s, REOP_range, len); + for(i = 0; i < cr->len; i += 2) { + dbuf_put_u16(&s->byte_code, cr->points[i]); + high = cr->points[i + 1] - 1; + if (high == UINT32_MAX - 1) + high = 0xffff; + dbuf_put_u16(&s->byte_code, high); + } + } else { + re_emit_op_u16(s, REOP_range32, len); + for(i = 0; i < cr->len; i += 2) { + dbuf_put_u32(&s->byte_code, cr->points[i]); + dbuf_put_u32(&s->byte_code, cr->points[i + 1] - 1); + } + } + } + return 0; +} + +static int re_parse_char_class(REParseState *s, const uint8_t **pp) +{ + const uint8_t *p; + uint32_t c1, c2; + CharRange cr_s, *cr = &cr_s; + CharRange cr1_s, *cr1 = &cr1_s; + BOOL invert; + + cr_init(cr, s->opaque, lre_realloc); + p = *pp; + p++; /* skip '[' */ + invert = FALSE; + if (*p == '^') { + p++; + invert = TRUE; + } + for(;;) { + if (*p == ']') + break; + c1 = get_class_atom(s, cr1, &p, TRUE); + if ((int)c1 < 0) + goto fail; + if (*p == '-' && p[1] != ']') { + const uint8_t *p0 = p + 1; + if (c1 >= CLASS_RANGE_BASE) { + if (s->is_utf16) { + cr_free(cr1); + goto invalid_class_range; + } + /* Annex B: match '-' character */ + goto class_atom; + } + c2 = get_class_atom(s, cr1, &p0, TRUE); + if ((int)c2 < 0) + goto fail; + if (c2 >= CLASS_RANGE_BASE) { + cr_free(cr1); + if (s->is_utf16) { + goto invalid_class_range; + } + /* Annex B: match '-' character */ + goto class_atom; + } + p = p0; + if (c2 < c1) { + invalid_class_range: + re_parse_error(s, "invalid class range"); + goto fail; + } + if (cr_union_interval(cr, c1, c2)) + goto memory_error; + } else { + class_atom: + if (c1 >= CLASS_RANGE_BASE) { + int ret; + ret = cr_union1(cr, cr1->points, cr1->len); + cr_free(cr1); + if (ret) + goto memory_error; + } else { + if (cr_union_interval(cr, c1, c1)) + goto memory_error; + } + } + } + if (s->ignore_case) { + if (cr_canonicalize(cr)) + goto memory_error; + } + if (invert) { + if (cr_invert(cr)) + goto memory_error; + } + if (re_emit_range(s, cr)) + goto fail; + cr_free(cr); + p++; /* skip ']' */ + *pp = p; + return 0; + memory_error: + re_parse_out_of_memory(s); + fail: + cr_free(cr); + return -1; +} + +/* Return: + 1 if the opcodes in bc_buf[] always advance the character pointer. + 0 if the character pointer may not be advanced. + -1 if the code may depend on side effects of its previous execution (backreference) +*/ +static int re_check_advance(const uint8_t *bc_buf, int bc_buf_len) +{ + int pos, opcode, ret, len, i; + uint32_t val, last; + BOOL has_back_reference; + uint8_t capture_bitmap[CAPTURE_COUNT_MAX]; + + ret = -2; /* not known yet */ + pos = 0; + has_back_reference = FALSE; + memset(capture_bitmap, 0, sizeof(capture_bitmap)); + + while (pos < bc_buf_len) { + opcode = bc_buf[pos]; + len = reopcode_info[opcode].size; + switch(opcode) { + case REOP_range: + val = get_u16(bc_buf + pos + 1); + len += val * 4; + goto simple_char; + case REOP_range32: + val = get_u16(bc_buf + pos + 1); + len += val * 8; + goto simple_char; + case REOP_char: + case REOP_char32: + case REOP_dot: + case REOP_any: + simple_char: + if (ret == -2) + ret = 1; + break; + case REOP_line_start: + case REOP_line_end: + case REOP_push_i32: + case REOP_push_char_pos: + case REOP_drop: + case REOP_word_boundary: + case REOP_not_word_boundary: + case REOP_prev: + /* no effect */ + break; + case REOP_save_start: + case REOP_save_end: + val = bc_buf[pos + 1]; + capture_bitmap[val] |= 1; + break; + case REOP_save_reset: + { + val = bc_buf[pos + 1]; + last = bc_buf[pos + 2]; + while (val < last) + capture_bitmap[val++] |= 1; + } + break; + case REOP_back_reference: + case REOP_backward_back_reference: + val = bc_buf[pos + 1]; + capture_bitmap[val] |= 2; + has_back_reference = TRUE; + break; + default: + /* safe behvior: we cannot predict the outcome */ + if (ret == -2) + ret = 0; + break; + } + pos += len; + } + if (has_back_reference) { + /* check if there is back reference which references a capture + made in the some code */ + for(i = 0; i < CAPTURE_COUNT_MAX; i++) { + if (capture_bitmap[i] == 3) + return -1; + } + } + if (ret == -2) + ret = 0; + return ret; +} + +/* return -1 if a simple quantifier cannot be used. Otherwise return + the number of characters in the atom. */ +static int re_is_simple_quantifier(const uint8_t *bc_buf, int bc_buf_len) +{ + int pos, opcode, len, count; + uint32_t val; + + count = 0; + pos = 0; + while (pos < bc_buf_len) { + opcode = bc_buf[pos]; + len = reopcode_info[opcode].size; + switch(opcode) { + case REOP_range: + val = get_u16(bc_buf + pos + 1); + len += val * 4; + goto simple_char; + case REOP_range32: + val = get_u16(bc_buf + pos + 1); + len += val * 8; + goto simple_char; + case REOP_char: + case REOP_char32: + case REOP_dot: + case REOP_any: + simple_char: + count++; + break; + case REOP_line_start: + case REOP_line_end: + case REOP_word_boundary: + case REOP_not_word_boundary: + break; + default: + return -1; + } + pos += len; + } + return count; +} + +/* '*pp' is the first char after '<' */ +static int re_parse_group_name(char *buf, int buf_size, + const uint8_t **pp, BOOL is_utf16) +{ + const uint8_t *p; + uint32_t c; + char *q; + + p = *pp; + q = buf; + for(;;) { + c = *p; + if (c == '\\') { + p++; + if (*p != 'u') + return -1; + c = lre_parse_escape(&p, is_utf16 * 2); + } else if (c == '>') { + break; + } else if (c >= 128) { + c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); + } else { + p++; + } + if (c > 0x10FFFF) + return -1; + if (q == buf) { + if (!lre_js_is_ident_first(c)) + return -1; + } else { + if (!lre_js_is_ident_next(c)) + return -1; + } + if ((q - buf + UTF8_CHAR_LEN_MAX + 1) > buf_size) + return -1; + if (c < 128) { + *q++ = c; + } else { + q += unicode_to_utf8((uint8_t*)q, c); + } + } + if (q == buf) + return -1; + *q = '\0'; + p++; + *pp = p; + return 0; +} + +/* if capture_name = NULL: return the number of captures + 1. + Otherwise, return the capture index corresponding to capture_name + or -1 if none */ +static int re_parse_captures(REParseState *s, int *phas_named_captures, + const char *capture_name) +{ + const uint8_t *p; + int capture_index; + char name[TMP_BUF_SIZE]; + + capture_index = 1; + *phas_named_captures = 0; + for (p = s->buf_start; p < s->buf_end; p++) { + switch (*p) { + case '(': + if (p[1] == '?') { + if (p[2] == '<' && p[3] != '=' && p[3] != '!') { + *phas_named_captures = 1; + /* potential named capture */ + if (capture_name) { + p += 3; + if (re_parse_group_name(name, sizeof(name), &p, + s->is_utf16) == 0) { + if (!strcmp(name, capture_name)) + return capture_index; + } + } + capture_index++; + if (capture_index >= CAPTURE_COUNT_MAX) + goto done; + } + } else { + capture_index++; + if (capture_index >= CAPTURE_COUNT_MAX) + goto done; + } + break; + case '\\': + p++; + break; + case '[': + for (p += 1 + (*p == ']'); p < s->buf_end && *p != ']'; p++) { + if (*p == '\\') + p++; + } + break; + } + } + done: + if (capture_name) + return -1; + else + return capture_index; +} + +static int re_count_captures(REParseState *s) +{ + if (s->total_capture_count < 0) { + s->total_capture_count = re_parse_captures(s, &s->has_named_captures, + NULL); + } + return s->total_capture_count; +} + +static BOOL re_has_named_captures(REParseState *s) +{ + if (s->has_named_captures < 0) + re_count_captures(s); + return s->has_named_captures; +} + +static int find_group_name(REParseState *s, const char *name) +{ + const char *p, *buf_end; + size_t len, name_len; + int capture_index; + + name_len = strlen(name); + p = (char *)s->group_names.buf; + buf_end = (char *)s->group_names.buf + s->group_names.size; + capture_index = 1; + while (p < buf_end) { + len = strlen(p); + if (len == name_len && memcmp(name, p, name_len) == 0) + return capture_index; + p += len + 1; + capture_index++; + } + return -1; +} + +static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir); + +static int re_parse_term(REParseState *s, BOOL is_backward_dir) +{ + const uint8_t *p; + int c, last_atom_start, quant_min, quant_max, last_capture_count; + BOOL greedy, add_zero_advance_check, is_neg, is_backward_lookahead; + CharRange cr_s, *cr = &cr_s; + + last_atom_start = -1; + last_capture_count = 0; + p = s->buf_ptr; + c = *p; + switch(c) { + case '^': + p++; + re_emit_op(s, REOP_line_start); + break; + case '$': + p++; + re_emit_op(s, REOP_line_end); + break; + case '.': + p++; + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + if (is_backward_dir) + re_emit_op(s, REOP_prev); + re_emit_op(s, s->dotall ? REOP_any : REOP_dot); + if (is_backward_dir) + re_emit_op(s, REOP_prev); + break; + case '{': + if (s->is_utf16) { + return re_parse_error(s, "syntax error"); + } else if (!is_digit(p[1])) { + /* Annex B: we accept '{' not followed by digits as a + normal atom */ + goto parse_class_atom; + } else { + const uint8_t *p1 = p + 1; + /* Annex B: error if it is like a repetition count */ + parse_digits(&p1, TRUE); + if (*p1 == ',') { + p1++; + if (is_digit(*p1)) { + parse_digits(&p1, TRUE); + } + } + if (*p1 != '}') { + goto parse_class_atom; + } + } + /* fall thru */ + case '*': + case '+': + case '?': + return re_parse_error(s, "nothing to repeat"); + case '(': + if (p[1] == '?') { + if (p[2] == ':') { + p += 3; + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + s->buf_ptr = p; + if (re_parse_disjunction(s, is_backward_dir)) + return -1; + p = s->buf_ptr; + if (re_parse_expect(s, &p, ')')) + return -1; + } else if ((p[2] == '=' || p[2] == '!')) { + is_neg = (p[2] == '!'); + is_backward_lookahead = FALSE; + p += 3; + goto lookahead; + } else if (p[2] == '<' && + (p[3] == '=' || p[3] == '!')) { + int pos; + is_neg = (p[3] == '!'); + is_backward_lookahead = TRUE; + p += 4; + /* lookahead */ + lookahead: + /* Annex B allows lookahead to be used as an atom for + the quantifiers */ + if (!s->is_utf16 && !is_backward_lookahead) { + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + } + pos = re_emit_op_u32(s, REOP_lookahead + is_neg, 0); + s->buf_ptr = p; + if (re_parse_disjunction(s, is_backward_lookahead)) + return -1; + p = s->buf_ptr; + if (re_parse_expect(s, &p, ')')) + return -1; + re_emit_op(s, REOP_match); + /* jump after the 'match' after the lookahead is successful */ + if (dbuf_error(&s->byte_code)) + return -1; + put_u32(s->byte_code.buf + pos, s->byte_code.size - (pos + 4)); + } else if (p[2] == '<') { + p += 3; + if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf), + &p, s->is_utf16)) { + return re_parse_error(s, "invalid group name"); + } + if (find_group_name(s, s->u.tmp_buf) > 0) { + return re_parse_error(s, "duplicate group name"); + } + /* group name with a trailing zero */ + dbuf_put(&s->group_names, (uint8_t *)s->u.tmp_buf, + strlen(s->u.tmp_buf) + 1); + s->has_named_captures = 1; + goto parse_capture; + } else { + return re_parse_error(s, "invalid group"); + } + } else { + int capture_index; + p++; + /* capture without group name */ + dbuf_putc(&s->group_names, 0); + parse_capture: + if (s->capture_count >= CAPTURE_COUNT_MAX) + return re_parse_error(s, "too many captures"); + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + capture_index = s->capture_count++; + re_emit_op_u8(s, REOP_save_start + is_backward_dir, + capture_index); + + s->buf_ptr = p; + if (re_parse_disjunction(s, is_backward_dir)) + return -1; + p = s->buf_ptr; + + re_emit_op_u8(s, REOP_save_start + 1 - is_backward_dir, + capture_index); + + if (re_parse_expect(s, &p, ')')) + return -1; + } + break; + case '\\': + switch(p[1]) { + case 'b': + case 'B': + re_emit_op(s, REOP_word_boundary + (p[1] != 'b')); + p += 2; + break; + case 'k': + { + const uint8_t *p1; + int dummy_res; + + p1 = p; + if (p1[2] != '<') { + /* annex B: we tolerate invalid group names in non + unicode mode if there is no named capture + definition */ + if (s->is_utf16 || re_has_named_captures(s)) + return re_parse_error(s, "expecting group name"); + else + goto parse_class_atom; + } + p1 += 3; + if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf), + &p1, s->is_utf16)) { + if (s->is_utf16 || re_has_named_captures(s)) + return re_parse_error(s, "invalid group name"); + else + goto parse_class_atom; + } + c = find_group_name(s, s->u.tmp_buf); + if (c < 0) { + /* no capture name parsed before, try to look + after (inefficient, but hopefully not common */ + c = re_parse_captures(s, &dummy_res, s->u.tmp_buf); + if (c < 0) { + if (s->is_utf16 || re_has_named_captures(s)) + return re_parse_error(s, "group name not defined"); + else + goto parse_class_atom; + } + } + p = p1; + } + goto emit_back_reference; + case '0': + p += 2; + c = 0; + if (s->is_utf16) { + if (is_digit(*p)) { + return re_parse_error(s, "invalid decimal escape in regular expression"); + } + } else { + /* Annex B.1.4: accept legacy octal */ + if (*p >= '0' && *p <= '7') { + c = *p++ - '0'; + if (*p >= '0' && *p <= '7') { + c = (c << 3) + *p++ - '0'; + } + } + } + goto normal_char; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': + case '9': + { + const uint8_t *q = ++p; + + c = parse_digits(&p, FALSE); + if (c < 0 || (c >= s->capture_count && c >= re_count_captures(s))) { + if (!s->is_utf16) { + /* Annex B.1.4: accept legacy octal */ + p = q; + if (*p <= '7') { + c = 0; + if (*p <= '3') + c = *p++ - '0'; + if (*p >= '0' && *p <= '7') { + c = (c << 3) + *p++ - '0'; + if (*p >= '0' && *p <= '7') { + c = (c << 3) + *p++ - '0'; + } + } + } else { + c = *p++; + } + goto normal_char; + } + return re_parse_error(s, "back reference out of range in regular expression"); + } + emit_back_reference: + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + re_emit_op_u8(s, REOP_back_reference + is_backward_dir, c); + } + break; + default: + goto parse_class_atom; + } + break; + case '[': + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + if (is_backward_dir) + re_emit_op(s, REOP_prev); + if (re_parse_char_class(s, &p)) + return -1; + if (is_backward_dir) + re_emit_op(s, REOP_prev); + break; + case ']': + case '}': + if (s->is_utf16) + return re_parse_error(s, "syntax error"); + goto parse_class_atom; + default: + parse_class_atom: + c = get_class_atom(s, cr, &p, FALSE); + if ((int)c < 0) + return -1; + normal_char: + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + if (is_backward_dir) + re_emit_op(s, REOP_prev); + if (c >= CLASS_RANGE_BASE) { + int ret; + /* Note: canonicalization is not needed */ + ret = re_emit_range(s, cr); + cr_free(cr); + if (ret) + return -1; + } else { + if (s->ignore_case) + c = lre_canonicalize(c, s->is_utf16); + if (c <= 0xffff) + re_emit_op_u16(s, REOP_char, c); + else + re_emit_op_u32(s, REOP_char32, c); + } + if (is_backward_dir) + re_emit_op(s, REOP_prev); + break; + } + + /* quantifier */ + if (last_atom_start >= 0) { + c = *p; + switch(c) { + case '*': + p++; + quant_min = 0; + quant_max = INT32_MAX; + goto quantifier; + case '+': + p++; + quant_min = 1; + quant_max = INT32_MAX; + goto quantifier; + case '?': + p++; + quant_min = 0; + quant_max = 1; + goto quantifier; + case '{': + { + const uint8_t *p1 = p; + /* As an extension (see ES6 annex B), we accept '{' not + followed by digits as a normal atom */ + if (!is_digit(p[1])) { + if (s->is_utf16) + goto invalid_quant_count; + break; + } + p++; + quant_min = parse_digits(&p, TRUE); + quant_max = quant_min; + if (*p == ',') { + p++; + if (is_digit(*p)) { + quant_max = parse_digits(&p, TRUE); + if (quant_max < quant_min) { + invalid_quant_count: + return re_parse_error(s, "invalid repetition count"); + } + } else { + quant_max = INT32_MAX; /* infinity */ + } + } + if (*p != '}' && !s->is_utf16) { + /* Annex B: normal atom if invalid '{' syntax */ + p = p1; + break; + } + if (re_parse_expect(s, &p, '}')) + return -1; + } + quantifier: + greedy = TRUE; + if (*p == '?') { + p++; + greedy = FALSE; + } + if (last_atom_start < 0) { + return re_parse_error(s, "nothing to repeat"); + } + if (greedy) { + int len, pos; + + if (quant_max > 0) { + /* specific optimization for simple quantifiers */ + if (dbuf_error(&s->byte_code)) + goto out_of_memory; + len = re_is_simple_quantifier(s->byte_code.buf + last_atom_start, + s->byte_code.size - last_atom_start); + if (len > 0) { + re_emit_op(s, REOP_match); + + if (dbuf_insert(&s->byte_code, last_atom_start, 17)) + goto out_of_memory; + pos = last_atom_start; + s->byte_code.buf[pos++] = REOP_simple_greedy_quant; + put_u32(&s->byte_code.buf[pos], + s->byte_code.size - last_atom_start - 17); + pos += 4; + put_u32(&s->byte_code.buf[pos], quant_min); + pos += 4; + put_u32(&s->byte_code.buf[pos], quant_max); + pos += 4; + put_u32(&s->byte_code.buf[pos], len); + pos += 4; + goto done; + } + } + + if (dbuf_error(&s->byte_code)) + goto out_of_memory; + add_zero_advance_check = (re_check_advance(s->byte_code.buf + last_atom_start, + s->byte_code.size - last_atom_start) == 0); + } else { + add_zero_advance_check = FALSE; + } + + { + int len, pos; + len = s->byte_code.size - last_atom_start; + if (quant_min == 0) { + /* need to reset the capture in case the atom is + not executed */ + if (last_capture_count != s->capture_count) { + if (dbuf_insert(&s->byte_code, last_atom_start, 3)) + goto out_of_memory; + s->byte_code.buf[last_atom_start++] = REOP_save_reset; + s->byte_code.buf[last_atom_start++] = last_capture_count; + s->byte_code.buf[last_atom_start++] = s->capture_count - 1; + } + if (quant_max == 0) { + s->byte_code.size = last_atom_start; + } else if (quant_max == 1) { + if (dbuf_insert(&s->byte_code, last_atom_start, 5)) + goto out_of_memory; + s->byte_code.buf[last_atom_start] = REOP_split_goto_first + + greedy; + put_u32(s->byte_code.buf + last_atom_start + 1, len); + } else if (quant_max == INT32_MAX) { + if (dbuf_insert(&s->byte_code, last_atom_start, 5 + add_zero_advance_check)) + goto out_of_memory; + s->byte_code.buf[last_atom_start] = REOP_split_goto_first + + greedy; + put_u32(s->byte_code.buf + last_atom_start + 1, + len + 5 + add_zero_advance_check); + if (add_zero_advance_check) { + /* avoid infinite loop by stoping the + recursion if no advance was made in the + atom (only works if the atom has no + side effect) */ + s->byte_code.buf[last_atom_start + 1 + 4] = REOP_push_char_pos; + re_emit_goto(s, REOP_bne_char_pos, last_atom_start); + } else { + re_emit_goto(s, REOP_goto, last_atom_start); + } + } else { + if (dbuf_insert(&s->byte_code, last_atom_start, 10)) + goto out_of_memory; + pos = last_atom_start; + s->byte_code.buf[pos++] = REOP_push_i32; + put_u32(s->byte_code.buf + pos, quant_max); + pos += 4; + s->byte_code.buf[pos++] = REOP_split_goto_first + greedy; + put_u32(s->byte_code.buf + pos, len + 5); + re_emit_goto(s, REOP_loop, last_atom_start + 5); + re_emit_op(s, REOP_drop); + } + } else if (quant_min == 1 && quant_max == INT32_MAX && + !add_zero_advance_check) { + re_emit_goto(s, REOP_split_next_first - greedy, + last_atom_start); + } else { + if (quant_min == 1) { + /* nothing to add */ + } else { + if (dbuf_insert(&s->byte_code, last_atom_start, 5)) + goto out_of_memory; + s->byte_code.buf[last_atom_start] = REOP_push_i32; + put_u32(s->byte_code.buf + last_atom_start + 1, + quant_min); + last_atom_start += 5; + re_emit_goto(s, REOP_loop, last_atom_start); + re_emit_op(s, REOP_drop); + } + if (quant_max == INT32_MAX) { + pos = s->byte_code.size; + re_emit_op_u32(s, REOP_split_goto_first + greedy, + len + 5 + add_zero_advance_check); + if (add_zero_advance_check) + re_emit_op(s, REOP_push_char_pos); + /* copy the atom */ + dbuf_put_self(&s->byte_code, last_atom_start, len); + if (add_zero_advance_check) + re_emit_goto(s, REOP_bne_char_pos, pos); + else + re_emit_goto(s, REOP_goto, pos); + } else if (quant_max > quant_min) { + re_emit_op_u32(s, REOP_push_i32, quant_max - quant_min); + pos = s->byte_code.size; + re_emit_op_u32(s, REOP_split_goto_first + greedy, len + 5); + /* copy the atom */ + dbuf_put_self(&s->byte_code, last_atom_start, len); + + re_emit_goto(s, REOP_loop, pos); + re_emit_op(s, REOP_drop); + } + } + last_atom_start = -1; + } + break; + default: + break; + } + } + done: + s->buf_ptr = p; + return 0; + out_of_memory: + return re_parse_out_of_memory(s); +} + +static int re_parse_alternative(REParseState *s, BOOL is_backward_dir) +{ + const uint8_t *p; + int ret; + size_t start, term_start, end, term_size; + + start = s->byte_code.size; + for(;;) { + p = s->buf_ptr; + if (p >= s->buf_end) + break; + if (*p == '|' || *p == ')') + break; + term_start = s->byte_code.size; + ret = re_parse_term(s, is_backward_dir); + if (ret) + return ret; + if (is_backward_dir) { + /* reverse the order of the terms (XXX: inefficient, but + speed is not really critical here) */ + end = s->byte_code.size; + term_size = end - term_start; + if (dbuf_realloc(&s->byte_code, end + term_size)) + return -1; + memmove(s->byte_code.buf + start + term_size, + s->byte_code.buf + start, + end - start); + memcpy(s->byte_code.buf + start, s->byte_code.buf + end, + term_size); + } + } + return 0; +} + +static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir) +{ + int start, len, pos; + + if (lre_check_stack_overflow(s->opaque, 0)) + return re_parse_error(s, "stack overflow"); + + start = s->byte_code.size; + if (re_parse_alternative(s, is_backward_dir)) + return -1; + while (*s->buf_ptr == '|') { + s->buf_ptr++; + + len = s->byte_code.size - start; + + /* insert a split before the first alternative */ + if (dbuf_insert(&s->byte_code, start, 5)) { + return re_parse_out_of_memory(s); + } + s->byte_code.buf[start] = REOP_split_next_first; + put_u32(s->byte_code.buf + start + 1, len + 5); + + pos = re_emit_op_u32(s, REOP_goto, 0); + + if (re_parse_alternative(s, is_backward_dir)) + return -1; + + /* patch the goto */ + len = s->byte_code.size - (pos + 4); + put_u32(s->byte_code.buf + pos, len); + } + return 0; +} + +/* the control flow is recursive so the analysis can be linear */ +static int compute_stack_size(const uint8_t *bc_buf, int bc_buf_len) +{ + int stack_size, stack_size_max, pos, opcode, len; + uint32_t val; + + stack_size = 0; + stack_size_max = 0; + bc_buf += RE_HEADER_LEN; + bc_buf_len -= RE_HEADER_LEN; + pos = 0; + while (pos < bc_buf_len) { + opcode = bc_buf[pos]; + len = reopcode_info[opcode].size; + assert(opcode < REOP_COUNT); + assert((pos + len) <= bc_buf_len); + switch(opcode) { + case REOP_push_i32: + case REOP_push_char_pos: + stack_size++; + if (stack_size > stack_size_max) { + if (stack_size > STACK_SIZE_MAX) + return -1; + stack_size_max = stack_size; + } + break; + case REOP_drop: + case REOP_bne_char_pos: + assert(stack_size > 0); + stack_size--; + break; + case REOP_range: + val = get_u16(bc_buf + pos + 1); + len += val * 4; + break; + case REOP_range32: + val = get_u16(bc_buf + pos + 1); + len += val * 8; + break; + } + pos += len; + } + return stack_size_max; +} + +/* 'buf' must be a zero terminated UTF-8 string of length buf_len. + Return NULL if error and allocate an error message in *perror_msg, + otherwise the compiled bytecode and its length in plen. +*/ +uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, + const char *buf, size_t buf_len, int re_flags, + void *opaque) +{ + REParseState s_s, *s = &s_s; + int stack_size; + BOOL is_sticky; + + memset(s, 0, sizeof(*s)); + s->opaque = opaque; + s->buf_ptr = (const uint8_t *)buf; + s->buf_end = s->buf_ptr + buf_len; + s->buf_start = s->buf_ptr; + s->re_flags = re_flags; + s->is_utf16 = ((re_flags & LRE_FLAG_UTF16) != 0); + is_sticky = ((re_flags & LRE_FLAG_STICKY) != 0); + s->ignore_case = ((re_flags & LRE_FLAG_IGNORECASE) != 0); + s->dotall = ((re_flags & LRE_FLAG_DOTALL) != 0); + s->capture_count = 1; + s->total_capture_count = -1; + s->has_named_captures = -1; + + dbuf_init2(&s->byte_code, opaque, lre_realloc); + dbuf_init2(&s->group_names, opaque, lre_realloc); + + dbuf_putc(&s->byte_code, re_flags); /* first element is the flags */ + dbuf_putc(&s->byte_code, 0); /* second element is the number of captures */ + dbuf_putc(&s->byte_code, 0); /* stack size */ + dbuf_put_u32(&s->byte_code, 0); /* bytecode length */ + + if (!is_sticky) { + /* iterate thru all positions (about the same as .*?( ... ) ) + . We do it without an explicit loop so that lock step + thread execution will be possible in an optimized + implementation */ + re_emit_op_u32(s, REOP_split_goto_first, 1 + 5); + re_emit_op(s, REOP_any); + re_emit_op_u32(s, REOP_goto, -(5 + 1 + 5)); + } + re_emit_op_u8(s, REOP_save_start, 0); + + if (re_parse_disjunction(s, FALSE)) { + error: + dbuf_free(&s->byte_code); + dbuf_free(&s->group_names); + pstrcpy(error_msg, error_msg_size, s->u.error_msg); + *plen = 0; + return NULL; + } + + re_emit_op_u8(s, REOP_save_end, 0); + + re_emit_op(s, REOP_match); + + if (*s->buf_ptr != '\0') { + re_parse_error(s, "extraneous characters at the end"); + goto error; + } + + if (dbuf_error(&s->byte_code)) { + re_parse_out_of_memory(s); + goto error; + } + + stack_size = compute_stack_size(s->byte_code.buf, s->byte_code.size); + if (stack_size < 0) { + re_parse_error(s, "too many imbricated quantifiers"); + goto error; + } + + s->byte_code.buf[RE_HEADER_CAPTURE_COUNT] = s->capture_count; + s->byte_code.buf[RE_HEADER_STACK_SIZE] = stack_size; + put_u32(s->byte_code.buf + 3, s->byte_code.size - RE_HEADER_LEN); + + /* add the named groups if needed */ + if (s->group_names.size + 1 > (size_t)s->capture_count) { + dbuf_put(&s->byte_code, s->group_names.buf, s->group_names.size); + s->byte_code.buf[RE_HEADER_FLAGS] |= LRE_FLAG_NAMED_GROUPS; + } + dbuf_free(&s->group_names); + +#ifdef DUMP_REOP + lre_dump_bytecode(s->byte_code.buf, s->byte_code.size); +#endif + + error_msg[0] = '\0'; + *plen = s->byte_code.size; + return s->byte_code.buf; +} + +static BOOL is_line_terminator(uint32_t c) +{ + return (c == '\n' || c == '\r' || c == CP_LS || c == CP_PS); +} + +static BOOL is_word_char(uint32_t c) +{ + return ((c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c == '_')); +} + +#if 0 +#define GET_CHAR(c, cptr, cbuf_end) \ + do { \ + if (cbuf_type == 0) { \ + c = *cptr++; \ + } else { \ + uint32_t __c1; \ + c = *(const uint16_t *)(const void *)cptr; \ + cptr += 2; \ + if (c >= 0xd800 && c < 0xdc00 && \ + cbuf_type == 2 && cptr < cbuf_end) { \ + __c1 = *(const uint16_t *)(const void *)cptr; \ + if (__c1 >= 0xdc00 && __c1 < 0xe000) { \ + c = (((c & 0x3ff) << 10) | (__c1 & 0x3ff)) + 0x10000; \ + cptr += 2; \ + } \ + } \ + } \ + } while (0) + +#define PEEK_CHAR(c, cptr, cbuf_end) \ + do { \ + if (cbuf_type == 0) { \ + c = cptr[0]; \ + } else { \ + uint32_t __c1; \ + c = ((const uint16_t *)(const void *)cptr)[0]; \ + if (c >= 0xd800 && c < 0xdc00 && \ + cbuf_type == 2 && (cptr + 2) < cbuf_end) { \ + __c1 = ((const uint16_t *)(const void *)cptr)[1]; \ + if (__c1 >= 0xdc00 && __c1 < 0xe000) { \ + c = (((c & 0x3ff) << 10) | (__c1 & 0x3ff)) + 0x10000; \ + } \ + } \ + } \ + } while (0) + +#define PEEK_PREV_CHAR(c, cptr, cbuf_start) \ + do { \ + if (cbuf_type == 0) { \ + c = cptr[-1]; \ + } else { \ + uint32_t __c1; \ + c = ((const uint16_t *)(const void *)cptr)[-1]; \ + if (c >= 0xdc00 && c < 0xe000 && \ + cbuf_type == 2 && (cptr - 4) >= cbuf_start) { \ + __c1 = ((const uint16_t *)(const void *)cptr)[-2]; \ + if (__c1 >= 0xd800 && __c1 < 0xdc00 ) { \ + c = (((__c1 & 0x3ff) << 10) | (c & 0x3ff)) + 0x10000; \ + } \ + } \ + } \ + } while (0) + +#define GET_PREV_CHAR(c, cptr, cbuf_start) \ + do { \ + if (cbuf_type == 0) { \ + cptr--; \ + c = cptr[0]; \ + } else { \ + uint32_t __c1; \ + cptr -= 2; \ + c = ((const uint16_t *)(const void *)cptr)[0]; \ + if (c >= 0xdc00 && c < 0xe000 && \ + cbuf_type == 2 && cptr > cbuf_start) { \ + __c1 = ((const uint16_t *)(const void *)cptr)[-1]; \ + if (__c1 >= 0xd800 && __c1 < 0xdc00 ) { \ + cptr -= 2; \ + c = (((__c1 & 0x3ff) << 10) | (c & 0x3ff)) + 0x10000; \ + } \ + } \ + } \ + } while (0) + +#define PREV_CHAR(cptr, cbuf_start) \ + do { \ + if (cbuf_type == 0) { \ + cptr--; \ + } else { \ + cptr -= 2; \ + if (cbuf_type == 2) { \ + c = ((const uint16_t *)(const void *)cptr)[0]; \ + if (c >= 0xdc00 && c < 0xe000 && cptr > cbuf_start) { \ + c = ((const uint16_t *)(const void *)cptr)[-1]; \ + if (c >= 0xd800 && c < 0xdc00) \ + cptr -= 2; \ + } \ + } \ + } \ + } while (0) +#else +struct EditBuffer; +unsigned int eb_nextc(struct EditBuffer *b, int offset, int *next_ptr); +unsigned int eb_prevc(struct EditBuffer *b, int offset, int *next_ptr); +#define GET_CHAR(c, cptr, cbuf_end) \ + do { \ + int offset = cptr - s->cbuf; \ + struct EditBuffer *b = unconst(void *)s->cbuf; \ + c = eb_nextc(b, offset, &offset); \ + cptr = s->cbuf + offset; \ + } while (0) + +#define PEEK_CHAR(c, cptr, cbuf_end) \ + do { \ + int offset = cptr - s->cbuf; \ + struct EditBuffer *b = unconst(void *)s->cbuf; \ + c = eb_nextc(b, offset, &offset); \ + } while (0) + +#define PEEK_PREV_CHAR(c, cptr, cbuf_start) \ + do { \ + int offset = cptr - s->cbuf; \ + struct EditBuffer *b = unconst(void *)s->cbuf; \ + c = eb_prevc(b, offset, &offset); \ + } while (0) + +#define GET_PREV_CHAR(c, cptr, cbuf_start) \ + do { \ + int offset = cptr - s->cbuf; \ + struct EditBuffer *b = unconst(void *)s->cbuf; \ + c = eb_prevc(b, offset, &offset); \ + cptr = s->cbuf + offset; \ + } while (0) + +#define PREV_CHAR(cptr, cbuf_start) \ + do { \ + int offset = cptr - s->cbuf; \ + struct EditBuffer *b = unconst(void *)s->cbuf; \ + eb_prevc(b, offset, &offset); \ + cptr = s->cbuf + offset; \ + } while (0) + +#endif + +typedef uintptr_t StackInt; + +typedef enum { + RE_EXEC_STATE_SPLIT, + RE_EXEC_STATE_LOOKAHEAD, + RE_EXEC_STATE_NEGATIVE_LOOKAHEAD, + RE_EXEC_STATE_GREEDY_QUANT, +} REExecStateEnum; + +typedef struct REExecState { + REExecStateEnum type : 8; + uint8_t stack_len; + size_t count; /* only used for RE_EXEC_STATE_GREEDY_QUANT */ + const uint8_t *cptr; + const uint8_t *pc; + const void *buf[0]; +} REExecState; + +typedef struct { + const uint8_t *cbuf; + const uint8_t *cbuf_end; + /* 0 = 8 bit chars, 1 = 16 bit chars, 2 = 16 bit chars, UTF-16 */ + int cbuf_type; + int capture_count; + int stack_size_max; + BOOL multi_line; + BOOL ignore_case; + BOOL is_utf16; + BOOL is_not_bol, is_not_eol, is_not_bow, is_not_eow; + void *opaque; /* used for stack overflow check */ + + size_t state_size; + uint8_t *state_stack; + size_t state_stack_size; + size_t state_stack_len; + unsigned int (*nextc)(const uint8_t *bc_buf, int offset, int *offsetp); + unsigned int (*prevc)(const uint8_t *bc_buf, int offset, int *offsetp); +} REExecContext; + +static int push_state(REExecContext *s, + const uint8_t **capture, + StackInt *stack, size_t stack_len, + const uint8_t *pc, const uint8_t *cptr, + REExecStateEnum type, size_t count) +{ + REExecState *rs; + uint8_t *new_stack; + size_t new_size, i, n; + StackInt *stack_buf; + + if (unlikely((s->state_stack_len + 1) > s->state_stack_size)) { + /* reallocate the stack */ + new_size = s->state_stack_size * 3 / 2; + if (new_size < 8) + new_size = 8; + new_stack = lre_realloc(s->opaque, s->state_stack, new_size * s->state_size); + if (!new_stack) + return -1; + s->state_stack_size = new_size; + s->state_stack = new_stack; + } + rs = (REExecState *)(void *)(s->state_stack + s->state_stack_len * s->state_size); + s->state_stack_len++; + rs->type = type; + rs->count = count; + rs->stack_len = stack_len; + rs->cptr = cptr; + rs->pc = pc; + n = 2 * s->capture_count; + for(i = 0; i < n; i++) + rs->buf[i] = capture[i]; + stack_buf = (StackInt *)(rs->buf + n); + for(i = 0; i < stack_len; i++) + stack_buf[i] = stack[i]; + return 0; +} + +/* return 1 if match, 0 if not match or -1 if error. */ +static intptr_t lre_exec_backtrack(REExecContext *s, const uint8_t **capture, + StackInt *stack, int stack_len, + const uint8_t *pc, const uint8_t *cptr, + BOOL no_recurse) +{ + int opcode, ret; + //int cbuf_type; + uint32_t val, c; + const uint8_t *cbuf_end; + + //cbuf_type = s->cbuf_type; + cbuf_end = s->cbuf_end; + + for(;;) { + // printf("top=%p: pc=%d\n", th_list.top, (int)(pc - (bc_buf + RE_HEADER_LEN))); + opcode = *pc++; + switch(opcode) { + case REOP_match: + { + REExecState *rs; + if (no_recurse) + return (intptr_t)cptr; + ret = 1; + goto recurse; + no_match: + if (no_recurse) + return 0; + ret = 0; + recurse: + for(;;) { + if (s->state_stack_len == 0) + return ret; + rs = (REExecState *)(void *)(s->state_stack + + (s->state_stack_len - 1) * s->state_size); + if (rs->type == RE_EXEC_STATE_SPLIT) { + if (!ret) { + pop_state: + memcpy(capture, rs->buf, + sizeof(capture[0]) * 2 * s->capture_count); + pop_state1: + pc = rs->pc; + cptr = rs->cptr; + stack_len = rs->stack_len; + memcpy(stack, rs->buf + 2 * s->capture_count, + stack_len * sizeof(stack[0])); + s->state_stack_len--; + break; + } + } else if (rs->type == RE_EXEC_STATE_GREEDY_QUANT) { + if (!ret) { + uint32_t char_count, i; + memcpy(capture, rs->buf, + sizeof(capture[0]) * 2 * s->capture_count); + stack_len = rs->stack_len; + memcpy(stack, rs->buf + 2 * s->capture_count, + stack_len * sizeof(stack[0])); + pc = rs->pc; + cptr = rs->cptr; + /* go backward */ + char_count = get_u32(pc + 12); + for(i = 0; i < char_count; i++) { + PREV_CHAR(cptr, s->cbuf); + } + pc = (pc + 16) + (int)get_u32(pc); + rs->cptr = cptr; + rs->count--; + if (rs->count == 0) { + s->state_stack_len--; + } + break; + } + } else { + ret = ((rs->type == RE_EXEC_STATE_LOOKAHEAD && ret) || + (rs->type == RE_EXEC_STATE_NEGATIVE_LOOKAHEAD && !ret)); + if (ret) { + /* keep the capture in case of positive lookahead */ + if (rs->type == RE_EXEC_STATE_LOOKAHEAD) + goto pop_state1; + else + goto pop_state; + } + } + s->state_stack_len--; + } + } + break; + case REOP_char32: + val = get_u32(pc); + pc += 4; + goto test_char; + case REOP_char: + val = get_u16(pc); + pc += 2; + test_char: + if (cptr >= cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end); + if (s->ignore_case) { + c = lre_canonicalize(c, s->is_utf16); + } + if (val != c) + goto no_match; + break; + case REOP_split_goto_first: + case REOP_split_next_first: + { + const uint8_t *pc1; + + val = get_u32(pc); + pc += 4; + if (opcode == REOP_split_next_first) { + pc1 = pc + (int)val; + } else { + pc1 = pc; + pc = pc + (int)val; + } + ret = push_state(s, capture, stack, stack_len, + pc1, cptr, RE_EXEC_STATE_SPLIT, 0); + if (ret < 0) + return -1; + break; + } + case REOP_lookahead: + case REOP_negative_lookahead: + val = get_u32(pc); + pc += 4; + ret = push_state(s, capture, stack, stack_len, + pc + (int)val, cptr, + RE_EXEC_STATE_LOOKAHEAD + opcode - REOP_lookahead, + 0); + if (ret < 0) + return -1; + break; + + case REOP_goto: + val = get_u32(pc); + pc += 4 + (int)val; + break; + case REOP_line_start: + if (cptr == s->cbuf) { + if (s->is_not_bol) + goto no_match; + break; + } + if (!s->multi_line) + goto no_match; + PEEK_PREV_CHAR(c, cptr, s->cbuf); + if (!is_line_terminator(c)) + goto no_match; + break; + case REOP_line_end: + if (cptr == cbuf_end) { + if (s->is_not_eol) + goto no_match; + break; + } + if (!s->multi_line) + goto no_match; + PEEK_CHAR(c, cptr, cbuf_end); + if (!is_line_terminator(c)) + goto no_match; + break; + case REOP_dot: + if (cptr == cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end); + if (is_line_terminator(c)) + goto no_match; + break; + case REOP_any: + if (cptr == cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end); + break; + case REOP_save_start: + case REOP_save_end: + val = *pc++; + assert(val < (uint32_t)s->capture_count); + capture[2 * val + opcode - REOP_save_start] = (const uint8_t *)cptr; + break; + case REOP_save_reset: + { + uint32_t val2; + val = pc[0]; + val2 = pc[1]; + pc += 2; + assert(val2 < (uint32_t)s->capture_count); + while (val <= val2) { + capture[2 * val] = NULL; + capture[2 * val + 1] = NULL; + val++; + } + } + break; + case REOP_push_i32: + val = get_u32(pc); + pc += 4; + stack[stack_len++] = val; + break; + case REOP_drop: + stack_len--; + break; + case REOP_loop: + val = get_u32(pc); + pc += 4; + if (--stack[stack_len - 1] != 0) { + pc += (int)val; + } + break; + case REOP_push_char_pos: + stack[stack_len++] = (uintptr_t)cptr; + break; + case REOP_bne_char_pos: + val = get_u32(pc); + pc += 4; + if (stack[--stack_len] != (uintptr_t)cptr) + pc += (int)val; + break; + case REOP_word_boundary: + case REOP_not_word_boundary: + { + BOOL v1, v2; + /* char before */ + if (cptr == s->cbuf) { + v1 = s->is_not_bow; + } else { + PEEK_PREV_CHAR(c, cptr, s->cbuf); + v1 = is_word_char(c); + } + /* current char */ + if (cptr >= cbuf_end) { + v2 = s->is_not_eow; + } else { + PEEK_CHAR(c, cptr, cbuf_end); + v2 = is_word_char(c); + } + if (v1 ^ v2 ^ (REOP_not_word_boundary - opcode)) + goto no_match; + } + break; + case REOP_back_reference: + case REOP_backward_back_reference: + { + const uint8_t *cptr1, *cptr1_end, *cptr1_start; + uint32_t c1, c2; + + val = *pc++; + if (val >= (uint32_t)s->capture_count) + goto no_match; + cptr1_start = capture[2 * val]; + cptr1_end = capture[2 * val + 1]; + if (!cptr1_start || !cptr1_end) + break; + if (opcode == REOP_back_reference) { + cptr1 = cptr1_start; + while (cptr1 < cptr1_end) { + if (cptr >= cbuf_end) + goto no_match; + GET_CHAR(c1, cptr1, cptr1_end); + GET_CHAR(c2, cptr, cbuf_end); + if (s->ignore_case) { + c1 = lre_canonicalize(c1, s->is_utf16); + c2 = lre_canonicalize(c2, s->is_utf16); + } + if (c1 != c2) + goto no_match; + } + } else { + cptr1 = cptr1_end; + while (cptr1 > cptr1_start) { + if (cptr == s->cbuf) + goto no_match; + GET_PREV_CHAR(c1, cptr1, cptr1_start); + GET_PREV_CHAR(c2, cptr, s->cbuf); + if (s->ignore_case) { + c1 = lre_canonicalize(c1, s->is_utf16); + c2 = lre_canonicalize(c2, s->is_utf16); + } + if (c1 != c2) + goto no_match; + } + } + } + break; + case REOP_range: + { + int n; + uint32_t low, high, idx_min, idx_max, idx; + + n = get_u16(pc); /* n must be >= 1 */ + pc += 2; + if (cptr >= cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end); + if (s->ignore_case) { + c = lre_canonicalize(c, s->is_utf16); + } + idx_min = 0; + low = get_u16(pc + 0 * 4); + if (c < low) + goto no_match; + idx_max = n - 1; + high = get_u16(pc + idx_max * 4 + 2); + /* 0xffff in for last value means +infinity */ + if (unlikely(c >= 0xffff) && high == 0xffff) + goto range_match; + if (c > high) + goto no_match; + while (idx_min <= idx_max) { + idx = (idx_min + idx_max) / 2; + low = get_u16(pc + idx * 4); + high = get_u16(pc + idx * 4 + 2); + if (c < low) + idx_max = idx - 1; + else if (c > high) + idx_min = idx + 1; + else + goto range_match; + } + goto no_match; + range_match: + pc += 4 * n; + } + break; + case REOP_range32: + { + int n; + uint32_t low, high, idx_min, idx_max, idx; + + n = get_u16(pc); /* n must be >= 1 */ + pc += 2; + if (cptr >= cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end); + if (s->ignore_case) { + c = lre_canonicalize(c, s->is_utf16); + } + idx_min = 0; + low = get_u32(pc + 0 * 8); + if (c < low) + goto no_match; + idx_max = n - 1; + high = get_u32(pc + idx_max * 8 + 4); + if (c > high) + goto no_match; + while (idx_min <= idx_max) { + idx = (idx_min + idx_max) / 2; + low = get_u32(pc + idx * 8); + high = get_u32(pc + idx * 8 + 4); + if (c < low) + idx_max = idx - 1; + else if (c > high) + idx_min = idx + 1; + else + goto range32_match; + } + goto no_match; + range32_match: + pc += 8 * n; + } + break; + case REOP_prev: + /* go to the previous char */ + if (cptr == s->cbuf) + goto no_match; + PREV_CHAR(cptr, s->cbuf); + break; + case REOP_simple_greedy_quant: + { + uint32_t next_pos, quant_min, quant_max; + size_t q; + intptr_t res; + const uint8_t *pc1; + + next_pos = get_u32(pc); + quant_min = get_u32(pc + 4); + quant_max = get_u32(pc + 8); + pc += 16; + pc1 = pc; + pc += (int)next_pos; + + q = 0; + for(;;) { + res = lre_exec_backtrack(s, capture, stack, stack_len, + pc1, cptr, TRUE); + if (res == -1) + return res; + if (!res) + break; + cptr = (uint8_t *)res; + q++; + if (q >= quant_max && quant_max != INT32_MAX) + break; + } + if (q < quant_min) + goto no_match; + if (q > quant_min) { + /* will examine all matches down to quant_min */ + ret = push_state(s, capture, stack, stack_len, + pc1 - 16, cptr, + RE_EXEC_STATE_GREEDY_QUANT, + q - quant_min); + if (ret < 0) + return -1; + } + } + break; + default: + abort(); + } + } +} + +/* Return 1 if match, 0 if not match or -1 if error. cindex is the + starting position of the match and must be such as 0 <= cindex <= + clen. */ +int lre_exec(uint8_t **capture, + const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, + int cbuf_type, void *opaque, uint32_t bof_char, uint32_t eof_char, + unsigned int (*nextc)(const uint8_t *bc_buf, int offset, int *offsetp), + unsigned int (*prevc)(const uint8_t *bc_buf, int offset, int *offsetp)) +{ + REExecContext s_s, *s = &s_s; + int re_flags, i, alloca_size, ret; + StackInt *stack_buf; + + re_flags = bc_buf[RE_HEADER_FLAGS]; + s->multi_line = (re_flags & LRE_FLAG_MULTILINE) != 0; + s->ignore_case = (re_flags & LRE_FLAG_IGNORECASE) != 0; + s->is_utf16 = (re_flags & LRE_FLAG_UTF16) != 0; + s->is_not_bol = FALSE; + s->is_not_eol = FALSE; + s->is_not_bow = FALSE; + s->is_not_eow = FALSE; + if (bof_char && bof_char != '\n') { + s->is_not_bol = TRUE; + s->is_not_bow = is_word_char(bof_char); + } + if (eof_char && eof_char != '\n') { + s->is_not_eol = TRUE; + s->is_not_eow = is_word_char(eof_char); + } + s->capture_count = bc_buf[RE_HEADER_CAPTURE_COUNT]; + s->stack_size_max = bc_buf[RE_HEADER_STACK_SIZE]; + s->cbuf = cbuf; + s->cbuf_end = cbuf + (clen << cbuf_type); + s->cbuf_type = cbuf_type; + if (s->cbuf_type == 1 && s->is_utf16) + s->cbuf_type = 2; + s->nextc = nextc; + s->prevc = prevc; + s->opaque = opaque; + + s->state_size = sizeof(REExecState) + + s->capture_count * sizeof(capture[0]) * 2 + + s->stack_size_max * sizeof(stack_buf[0]); + s->state_stack = NULL; + s->state_stack_len = 0; + s->state_stack_size = 0; + + for(i = 0; i < s->capture_count * 2; i++) + capture[i] = NULL; + alloca_size = s->stack_size_max * sizeof(stack_buf[0]); + stack_buf = alloca(alloca_size); + ret = lre_exec_backtrack(s, (const uint8_t **)(void *)capture, + stack_buf, 0, bc_buf + RE_HEADER_LEN, + cbuf + (cindex << cbuf_type), FALSE); + lre_realloc(s->opaque, s->state_stack, 0); + return ret; +} + +int lre_get_capture_count(const uint8_t *bc_buf) +{ + return bc_buf[RE_HEADER_CAPTURE_COUNT]; +} + +int lre_get_flags(const uint8_t *bc_buf) +{ + return bc_buf[RE_HEADER_FLAGS]; +} + +/* Return NULL if no group names. Otherwise, return a pointer to + 'capture_count - 1' zero terminated UTF-8 strings. */ +const char *lre_get_groupnames(const uint8_t *bc_buf) +{ + uint32_t re_bytecode_len; + if ((lre_get_flags(bc_buf) & LRE_FLAG_NAMED_GROUPS) == 0) + return NULL; + re_bytecode_len = get_u32(bc_buf + 3); + return (const char *)(bc_buf + 7 + re_bytecode_len); +} + +#ifdef TEST + +BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size) +{ + return FALSE; +} + +void *lre_realloc(void *opaque, void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +int main(int argc, char **argv) +{ + int len, ret, i; + uint8_t *bc; + char error_msg[64]; + uint8_t *capture[CAPTURE_COUNT_MAX * 2]; + const char *input; + int input_len, capture_count; + + if (argc < 3) { + printf("usage: %s regexp input\n", argv[0]); + exit(1); + } + bc = lre_compile(&len, error_msg, sizeof(error_msg), argv[1], + strlen(argv[1]), 0, NULL); + if (!bc) { + fprintf(stderr, "error: %s\n", error_msg); + exit(1); + } + + input = argv[2]; + input_len = strlen(input); + + ret = lre_exec(capture, bc, (uint8_t *)input, 0, input_len, 0, NULL, 0, 0, NULL, NULL); + printf("ret=%d\n", ret); + if (ret == 1) { + capture_count = lre_get_capture_count(bc); + for(i = 0; i < 2 * capture_count; i++) { + uint8_t *ptr; + ptr = capture[i]; + printf("%d: ", i); + if (!ptr) + printf(""); + else + printf("%u", (int)(ptr - (uint8_t *)input)); + printf("\n"); + } + } + return 0; +} +#endif diff --git a/libregexp.h b/libregexp.h new file mode 100644 index 0000000..bd073a8 --- /dev/null +++ b/libregexp.h @@ -0,0 +1,94 @@ +/* + * Regular Expression Engine + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * 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. + */ +#ifndef LIBREGEXP_H +#define LIBREGEXP_H + +#include + +#include "libunicode.h" + +#define LRE_BOOL int /* for documentation purposes */ + +#define LRE_FLAG_GLOBAL (1 << 0) +#define LRE_FLAG_IGNORECASE (1 << 1) +#define LRE_FLAG_MULTILINE (1 << 2) +#define LRE_FLAG_DOTALL (1 << 3) +#define LRE_FLAG_UTF16 (1 << 4) +#define LRE_FLAG_STICKY (1 << 5) + +#define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ + +uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, + const char *buf, size_t buf_len, int re_flags, + void *opaque); +int lre_get_capture_count(const uint8_t *bc_buf); +int lre_get_flags(const uint8_t *bc_buf); +const char *lre_get_groupnames(const uint8_t *bc_buf); +int lre_exec(uint8_t **capture, + const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, + int cbuf_type, void *opaque, uint32_t bof_char, uint32_t eof_char, + unsigned int (*nextc)(const uint8_t *bc_buf, int offset, int *offsetp), + unsigned int (*prevc)(const uint8_t *bc_buf, int offset, int *offsetp)); + +int lre_parse_escape(const uint8_t **pp, int allow_utf16); +LRE_BOOL lre_is_space(int c); + +/* must be provided by the user */ +LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size); +void *lre_realloc(void *opaque, void *ptr, size_t size); + +/* JS identifier test */ +extern uint32_t const lre_id_start_table_ascii[4]; +extern uint32_t const lre_id_continue_table_ascii[4]; + +static inline int lre_js_is_ident_first(int c) +{ + if ((uint32_t)c < 128) { + return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1; + } else { +#ifdef CONFIG_ALL_UNICODE + return lre_is_id_start(c); +#else + return !lre_is_space(c); +#endif + } +} + +static inline int lre_js_is_ident_next(int c) +{ + if ((uint32_t)c < 128) { + return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1; + } else { + /* ZWNJ and ZWJ are accepted in identifiers */ +#ifdef CONFIG_ALL_UNICODE + return lre_is_id_continue(c) || c == 0x200C || c == 0x200D; +#else + return !lre_is_space(c) || c == 0x200C || c == 0x200D; +#endif + } +} + +#undef LRE_BOOL + +#endif /* LIBREGEXP_H */ diff --git a/libunicode-table.h b/libunicode-table.h new file mode 100644 index 0000000..1727525 --- /dev/null +++ b/libunicode-table.h @@ -0,0 +1,4449 @@ +/* Compressed unicode tables */ +/* Automatically generated file - do not edit */ + +#include + +static const uint32_t case_conv_table1[370] = { + 0x00209a30, 0x00309a00, 0x005a8173, 0x00601730, + 0x006c0730, 0x006f81b3, 0x00701700, 0x007c0700, + 0x007f8100, 0x00803040, 0x009801c3, 0x00988190, + 0x00990640, 0x009c9040, 0x00a481b4, 0x00a52e40, + 0x00bc0130, 0x00bc8640, 0x00bf8170, 0x00c00100, + 0x00c08130, 0x00c10440, 0x00c30130, 0x00c38240, + 0x00c48230, 0x00c58240, 0x00c70130, 0x00c78130, + 0x00c80130, 0x00c88240, 0x00c98130, 0x00ca0130, + 0x00ca8100, 0x00cb0130, 0x00cb8130, 0x00cc0240, + 0x00cd0100, 0x00ce0130, 0x00ce8130, 0x00cf0100, + 0x00cf8130, 0x00d00640, 0x00d30130, 0x00d38240, + 0x00d48130, 0x00d60240, 0x00d70130, 0x00d78240, + 0x00d88230, 0x00d98440, 0x00db8130, 0x00dc0240, + 0x00de0240, 0x00df8100, 0x00e20350, 0x00e38350, + 0x00e50350, 0x00e69040, 0x00ee8100, 0x00ef1240, + 0x00f801b4, 0x00f88350, 0x00fa0240, 0x00fb0130, + 0x00fb8130, 0x00fc2840, 0x01100130, 0x01111240, + 0x011d0131, 0x011d8240, 0x011e8130, 0x011f0131, + 0x011f8201, 0x01208240, 0x01218130, 0x01220130, + 0x01228130, 0x01230a40, 0x01280101, 0x01288101, + 0x01290101, 0x01298100, 0x012a0100, 0x012b0200, + 0x012c8100, 0x012d8100, 0x012e0101, 0x01300100, + 0x01308101, 0x01318100, 0x01328101, 0x01330101, + 0x01340100, 0x01348100, 0x01350101, 0x01358101, + 0x01360101, 0x01378100, 0x01388101, 0x01390100, + 0x013a8100, 0x013e8101, 0x01400100, 0x01410101, + 0x01418100, 0x01438101, 0x01440100, 0x01448100, + 0x01450200, 0x01460100, 0x01490100, 0x014e8101, + 0x014f0101, 0x01a28173, 0x01b80440, 0x01bb0240, + 0x01bd8300, 0x01bf8130, 0x01c30130, 0x01c40330, + 0x01c60130, 0x01c70230, 0x01c801d0, 0x01c89130, + 0x01d18930, 0x01d60100, 0x01d68300, 0x01d801d3, + 0x01d89100, 0x01e10173, 0x01e18900, 0x01e60100, + 0x01e68200, 0x01e78130, 0x01e80173, 0x01e88173, + 0x01ea8173, 0x01eb0173, 0x01eb8100, 0x01ec1840, + 0x01f80173, 0x01f88173, 0x01f90100, 0x01f98100, + 0x01fa01a0, 0x01fa8173, 0x01fb8240, 0x01fc8130, + 0x01fd0240, 0x01fe8330, 0x02001030, 0x02082030, + 0x02182000, 0x02281000, 0x02302240, 0x02453640, + 0x02600130, 0x02608e40, 0x02678100, 0x02686040, + 0x0298a630, 0x02b0a600, 0x02c381b5, 0x08502631, + 0x08638131, 0x08668131, 0x08682b00, 0x087e8300, + 0x09d05011, 0x09f80610, 0x09fc0620, 0x0e400174, + 0x0e408174, 0x0e410174, 0x0e418174, 0x0e420174, + 0x0e428174, 0x0e430174, 0x0e438180, 0x0e440180, + 0x0e482b30, 0x0e5e8330, 0x0ebc8101, 0x0ebe8101, + 0x0ec70101, 0x0f007e40, 0x0f3f1840, 0x0f4b01b5, + 0x0f4b81b6, 0x0f4c01b6, 0x0f4c81b6, 0x0f4d01b7, + 0x0f4d8180, 0x0f4f0130, 0x0f506040, 0x0f800800, + 0x0f840830, 0x0f880600, 0x0f8c0630, 0x0f900800, + 0x0f940830, 0x0f980800, 0x0f9c0830, 0x0fa00600, + 0x0fa40630, 0x0fa801b0, 0x0fa88100, 0x0fa901d3, + 0x0fa98100, 0x0faa01d3, 0x0faa8100, 0x0fab01d3, + 0x0fab8100, 0x0fac8130, 0x0fad8130, 0x0fae8130, + 0x0faf8130, 0x0fb00800, 0x0fb40830, 0x0fb80200, + 0x0fb90400, 0x0fbb0200, 0x0fbc0201, 0x0fbd0201, + 0x0fbe0201, 0x0fc008b7, 0x0fc40867, 0x0fc808b8, + 0x0fcc0868, 0x0fd008b8, 0x0fd40868, 0x0fd80200, + 0x0fd901b9, 0x0fd981b1, 0x0fda01b9, 0x0fdb01b1, + 0x0fdb81d7, 0x0fdc0230, 0x0fdd0230, 0x0fde0161, + 0x0fdf0173, 0x0fe101b9, 0x0fe181b2, 0x0fe201ba, + 0x0fe301b2, 0x0fe381d8, 0x0fe40430, 0x0fe60162, + 0x0fe80200, 0x0fe901d0, 0x0fe981d0, 0x0feb01b0, + 0x0feb81d0, 0x0fec0230, 0x0fed0230, 0x0ff00201, + 0x0ff101d3, 0x0ff181d3, 0x0ff201ba, 0x0ff28101, + 0x0ff301b0, 0x0ff381d3, 0x0ff40230, 0x0ff50230, + 0x0ff60131, 0x0ff901ba, 0x0ff981b2, 0x0ffa01bb, + 0x0ffb01b2, 0x0ffb81d9, 0x0ffc0230, 0x0ffd0230, + 0x0ffe0162, 0x109301a0, 0x109501a0, 0x109581a0, + 0x10990131, 0x10a70101, 0x10b01031, 0x10b81001, + 0x10c18240, 0x125b1a31, 0x12681a01, 0x16003031, + 0x16183001, 0x16300240, 0x16310130, 0x16318130, + 0x16320130, 0x16328100, 0x16330100, 0x16338640, + 0x16368130, 0x16370130, 0x16378130, 0x16380130, + 0x16390240, 0x163a8240, 0x163f0230, 0x16406440, + 0x16758440, 0x16790240, 0x16802600, 0x16938100, + 0x16968100, 0x53202e40, 0x53401c40, 0x53910e40, + 0x53993e40, 0x53bc8440, 0x53be8130, 0x53bf0a40, + 0x53c58240, 0x53c68130, 0x53c80440, 0x53ca0101, + 0x53cb1440, 0x53d50130, 0x53d58130, 0x53d60130, + 0x53d68130, 0x53d70130, 0x53d80130, 0x53d88130, + 0x53d90130, 0x53d98131, 0x53da1040, 0x53e20131, + 0x53e28130, 0x53e30130, 0x53e38440, 0x53e80240, + 0x53eb0440, 0x53fa8240, 0x55a98101, 0x55b85020, + 0x7d8001b2, 0x7d8081b2, 0x7d8101b2, 0x7d8181da, + 0x7d8201da, 0x7d8281b3, 0x7d8301b3, 0x7d8981bb, + 0x7d8a01bb, 0x7d8a81bb, 0x7d8b01bc, 0x7d8b81bb, + 0x7f909a31, 0x7fa09a01, 0x82002831, 0x82142801, + 0x82582431, 0x826c2401, 0x82b80b31, 0x82be0f31, + 0x82c60731, 0x82ca0231, 0x82cb8b01, 0x82d18f01, + 0x82d98701, 0x82dd8201, 0x86403331, 0x86603301, + 0x8c502031, 0x8c602001, 0xb7202031, 0xb7302001, + 0xf4802231, 0xf4912201, +}; + +static const uint8_t case_conv_table2[370] = { + 0x01, 0x00, 0x9c, 0x06, 0x07, 0x4d, 0x03, 0x04, + 0x10, 0x00, 0x8f, 0x0b, 0x00, 0x00, 0x11, 0x00, + 0x08, 0x00, 0x53, 0x4a, 0x51, 0x00, 0x52, 0x00, + 0x53, 0x00, 0x3a, 0x54, 0x55, 0x00, 0x57, 0x59, + 0x3f, 0x5d, 0x5c, 0x00, 0x46, 0x61, 0x63, 0x42, + 0x64, 0x00, 0x66, 0x00, 0x68, 0x00, 0x6a, 0x00, + 0x6c, 0x00, 0x6e, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x1a, 0x00, 0x93, 0x00, 0x00, 0x20, + 0x35, 0x00, 0x27, 0x00, 0x21, 0x00, 0x24, 0x22, + 0x2a, 0x00, 0x13, 0x6b, 0x6d, 0x00, 0x26, 0x24, + 0x27, 0x14, 0x16, 0x18, 0x1b, 0x1c, 0x3e, 0x1e, + 0x3f, 0x1f, 0x39, 0x3d, 0x22, 0x21, 0x41, 0x1e, + 0x40, 0x25, 0x25, 0x26, 0x28, 0x20, 0x2a, 0x48, + 0x2c, 0x43, 0x2e, 0x4b, 0x30, 0x4c, 0x32, 0x44, + 0x42, 0x99, 0x00, 0x00, 0x95, 0x8f, 0x7d, 0x7e, + 0x83, 0x84, 0x12, 0x80, 0x82, 0x76, 0x77, 0x12, + 0x7b, 0xa3, 0x7c, 0x78, 0x79, 0x8a, 0x92, 0x98, + 0xa6, 0xa0, 0x85, 0x00, 0x9a, 0xa1, 0x93, 0x75, + 0x33, 0x95, 0x00, 0x8e, 0x00, 0x74, 0x99, 0x98, + 0x97, 0x96, 0x00, 0x00, 0x9e, 0x00, 0x9c, 0x00, + 0xa1, 0xa0, 0x15, 0x2e, 0x2f, 0x30, 0xb4, 0xb5, + 0x4f, 0xaa, 0xa9, 0x12, 0x14, 0x1e, 0x21, 0x22, + 0x22, 0x2a, 0x34, 0x35, 0xa6, 0xa7, 0x36, 0x1f, + 0x49, 0x00, 0x00, 0x97, 0x01, 0x5a, 0xda, 0x1d, + 0x36, 0x05, 0x00, 0xc4, 0xc3, 0xc6, 0xc5, 0xc8, + 0xc7, 0xca, 0xc9, 0xcc, 0xcb, 0xc4, 0xd5, 0x45, + 0xd6, 0x42, 0xd7, 0x46, 0xd8, 0xce, 0xd0, 0xd2, + 0xd4, 0xda, 0xd9, 0xee, 0xf6, 0xfe, 0x0e, 0x07, + 0x0f, 0x80, 0x9f, 0x00, 0x21, 0x80, 0xa3, 0xed, + 0x00, 0xc0, 0x40, 0xc6, 0x60, 0xe7, 0xdb, 0xe6, + 0x99, 0xc0, 0x00, 0x00, 0x06, 0x60, 0xdc, 0x29, + 0xfd, 0x15, 0x12, 0x06, 0x16, 0xf8, 0xdd, 0x06, + 0x15, 0x12, 0x84, 0x08, 0xc6, 0x16, 0xff, 0xdf, + 0x03, 0xc0, 0x40, 0x00, 0x46, 0x60, 0xde, 0xe0, + 0x6d, 0x37, 0x38, 0x39, 0x15, 0x14, 0x17, 0x16, + 0x00, 0x1a, 0x19, 0x1c, 0x1b, 0x00, 0x5f, 0xb7, + 0x65, 0x44, 0x47, 0x00, 0x4f, 0x62, 0x4e, 0x50, + 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0xa3, 0xa4, + 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x00, + 0x00, 0x5a, 0x00, 0x47, 0x00, 0x5b, 0x56, 0x58, + 0x60, 0x5e, 0x70, 0x69, 0x6f, 0x4e, 0x00, 0x3b, + 0x67, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa8, + 0x8a, 0x8b, 0x8c, 0xab, 0xac, 0x58, 0x58, 0xaf, + 0x94, 0xb0, 0x6f, 0xb2, 0x5d, 0x5c, 0x5f, 0x5e, + 0x61, 0x60, 0x66, 0x67, 0x68, 0x69, 0x62, 0x63, + 0x64, 0x65, 0x6b, 0x6a, 0x6d, 0x6c, 0x6f, 0x6e, + 0x71, 0x70, +}; + +static const uint16_t case_conv_ext[58] = { + 0x0399, 0x0308, 0x0301, 0x03a5, 0x0313, 0x0300, 0x0342, 0x0391, + 0x0397, 0x03a9, 0x0046, 0x0049, 0x004c, 0x0053, 0x0069, 0x0307, + 0x02bc, 0x004e, 0x004a, 0x030c, 0x0535, 0x0552, 0x0048, 0x0331, + 0x0054, 0x0057, 0x030a, 0x0059, 0x0041, 0x02be, 0x1f08, 0x1f80, + 0x1f28, 0x1f90, 0x1f68, 0x1fa0, 0x1fba, 0x0386, 0x1fb3, 0x1fca, + 0x0389, 0x1fc3, 0x03a1, 0x1ffa, 0x038f, 0x1ff3, 0x0544, 0x0546, + 0x053b, 0x054e, 0x053d, 0x03b8, 0x0462, 0xa64a, 0x1e60, 0x03c9, + 0x006b, 0x00e5, +}; + +static const uint8_t unicode_prop_Cased1_table[188] = { + 0x40, 0xa9, 0x80, 0x8e, 0x80, 0xfc, 0x80, 0xd3, + 0x80, 0x8c, 0x80, 0x8d, 0x81, 0x8d, 0x02, 0x80, + 0xe1, 0x80, 0x91, 0x85, 0x9a, 0x01, 0x00, 0x01, + 0x11, 0x00, 0x01, 0x04, 0x08, 0x01, 0x08, 0x30, + 0x08, 0x01, 0x15, 0x20, 0x00, 0x39, 0x99, 0x31, + 0x9d, 0x84, 0x40, 0x94, 0x80, 0xd6, 0x82, 0xa6, + 0x80, 0x41, 0x62, 0x80, 0xa6, 0x80, 0x57, 0x76, + 0xf8, 0x02, 0x80, 0x8f, 0x80, 0xb0, 0x40, 0xdb, + 0x08, 0x80, 0x41, 0xd0, 0x80, 0x8c, 0x80, 0x8f, + 0x8c, 0xe4, 0x03, 0x01, 0x89, 0x00, 0x14, 0x28, + 0x10, 0x11, 0x02, 0x01, 0x18, 0x0b, 0x24, 0x4b, + 0x26, 0x01, 0x01, 0x86, 0xe5, 0x80, 0x60, 0x79, + 0xb6, 0x81, 0x40, 0x91, 0x81, 0xbd, 0x88, 0x94, + 0x05, 0x80, 0x98, 0x80, 0xa2, 0x00, 0x80, 0xa1, + 0x82, 0x43, 0x34, 0xa2, 0x06, 0x80, 0x8c, 0x60, + 0x5c, 0x16, 0x01, 0x10, 0xa9, 0x80, 0x88, 0x60, + 0xcc, 0x44, 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, + 0x0b, 0x80, 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, + 0x0f, 0x06, 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, + 0x80, 0x41, 0x53, 0x81, 0x98, 0x80, 0x98, 0x80, + 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, + 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x07, + 0x47, 0x33, 0x89, 0x80, 0x93, 0x52, 0x10, 0x99, + 0x85, 0x99, 0x85, 0x99, +}; + +static const uint8_t unicode_prop_Cased1_index[18] = { + 0xb9, 0x02, 0xe0, 0xa0, 0x1e, 0x40, 0x9e, 0xa6, + 0x40, 0x55, 0xd4, 0x61, 0xfb, 0xd6, 0x21, 0x8a, + 0xf1, 0x01, +}; + +static const uint8_t unicode_prop_Case_Ignorable_table[720] = { + 0xa6, 0x05, 0x80, 0x8a, 0x80, 0xa2, 0x00, 0x80, + 0xc6, 0x03, 0x00, 0x03, 0x01, 0x81, 0x41, 0xf6, + 0x40, 0xbf, 0x19, 0x18, 0x88, 0x08, 0x80, 0x40, + 0xfa, 0x86, 0x40, 0xce, 0x04, 0x80, 0xb0, 0xac, + 0x00, 0x01, 0x01, 0x00, 0xab, 0x80, 0x8a, 0x85, + 0x89, 0x8a, 0x00, 0xa2, 0x80, 0x89, 0x94, 0x8f, + 0x80, 0xe4, 0x38, 0x89, 0x03, 0xa0, 0x00, 0x80, + 0x9d, 0x9a, 0xda, 0x8a, 0xb9, 0x8a, 0x18, 0x08, + 0x97, 0x97, 0xaa, 0x82, 0xab, 0x06, 0x0d, 0x87, + 0xa8, 0xb9, 0xb6, 0x00, 0x03, 0x3b, 0x02, 0x86, + 0x89, 0x81, 0x8c, 0x80, 0x8e, 0x80, 0xb9, 0x03, + 0x1f, 0x80, 0x93, 0x81, 0x99, 0x01, 0x81, 0xb8, + 0x03, 0x0b, 0x09, 0x12, 0x80, 0x9d, 0x0a, 0x80, + 0x8a, 0x81, 0xb8, 0x03, 0x20, 0x0b, 0x80, 0x93, + 0x81, 0x95, 0x28, 0x80, 0xb9, 0x01, 0x00, 0x1f, + 0x06, 0x81, 0x8a, 0x81, 0x9d, 0x80, 0xbc, 0x80, + 0x8b, 0x80, 0xb1, 0x02, 0x80, 0xb6, 0x00, 0x14, + 0x10, 0x1e, 0x81, 0x8a, 0x81, 0x9c, 0x80, 0xb9, + 0x01, 0x05, 0x04, 0x81, 0x93, 0x81, 0x9b, 0x81, + 0xb8, 0x0b, 0x1f, 0x80, 0x93, 0x81, 0x9c, 0x80, + 0xc7, 0x06, 0x10, 0x80, 0xd9, 0x01, 0x86, 0x8a, + 0x88, 0xe1, 0x01, 0x88, 0x88, 0x00, 0x85, 0xc9, + 0x81, 0x9a, 0x00, 0x00, 0x80, 0xb6, 0x8d, 0x04, + 0x01, 0x84, 0x8a, 0x80, 0xa3, 0x88, 0x80, 0xe5, + 0x18, 0x28, 0x09, 0x81, 0x98, 0x0b, 0x82, 0x8f, + 0x83, 0x8c, 0x01, 0x0d, 0x80, 0x8e, 0x80, 0xdd, + 0x80, 0x42, 0x5f, 0x82, 0x43, 0xb1, 0x82, 0x9c, + 0x81, 0x9d, 0x81, 0x9d, 0x81, 0xbf, 0x08, 0x37, + 0x01, 0x8a, 0x10, 0x20, 0xac, 0x84, 0xb2, 0x80, + 0xc0, 0x81, 0xa1, 0x80, 0xf5, 0x13, 0x81, 0x88, + 0x05, 0x82, 0x40, 0xda, 0x09, 0x80, 0xb9, 0x00, + 0x30, 0x00, 0x01, 0x3d, 0x89, 0x08, 0xa6, 0x07, + 0x9e, 0xb0, 0x83, 0xaf, 0x00, 0x20, 0x04, 0x80, + 0xa7, 0x88, 0x8b, 0x81, 0x9f, 0x19, 0x08, 0x82, + 0xb7, 0x00, 0x0a, 0x00, 0x82, 0xb9, 0x39, 0x81, + 0xbf, 0x85, 0xd1, 0x10, 0x8c, 0x06, 0x18, 0x28, + 0x11, 0xb1, 0xbe, 0x8c, 0x80, 0xa1, 0xe4, 0x41, + 0xbc, 0x00, 0x82, 0x8a, 0x82, 0x8c, 0x82, 0x8c, + 0x82, 0x8c, 0x81, 0x8b, 0x27, 0x81, 0x89, 0x01, + 0x01, 0x84, 0xb0, 0x20, 0x89, 0x00, 0x8c, 0x80, + 0x8f, 0x8c, 0xb2, 0xa0, 0x4b, 0x8a, 0x81, 0xf0, + 0x82, 0xfc, 0x80, 0x8e, 0x80, 0xdf, 0x9f, 0xae, + 0x80, 0x41, 0xd4, 0x80, 0xa3, 0x1a, 0x24, 0x80, + 0xdc, 0x85, 0xdc, 0x82, 0x60, 0x6f, 0x15, 0x80, + 0x44, 0xe1, 0x85, 0x41, 0x0d, 0x80, 0xe1, 0x18, + 0x89, 0x00, 0x9b, 0x83, 0xcf, 0x81, 0x8d, 0xa1, + 0xcd, 0x80, 0x96, 0x82, 0xe6, 0x12, 0x0f, 0x02, + 0x03, 0x80, 0x98, 0x0c, 0x80, 0x40, 0x96, 0x81, + 0x99, 0x91, 0x8c, 0x80, 0xa5, 0x87, 0x98, 0x8a, + 0xad, 0x82, 0xaf, 0x01, 0x19, 0x81, 0x90, 0x80, + 0x94, 0x81, 0xc1, 0x29, 0x09, 0x81, 0x8b, 0x07, + 0x80, 0xa2, 0x80, 0x8a, 0x80, 0xb2, 0x00, 0x11, + 0x0c, 0x08, 0x80, 0x9a, 0x80, 0x8d, 0x0c, 0x08, + 0x80, 0xe3, 0x84, 0x88, 0x82, 0xf8, 0x01, 0x03, + 0x80, 0x60, 0x4f, 0x2f, 0x80, 0x40, 0x92, 0x90, + 0x42, 0x3c, 0x8f, 0x10, 0x8b, 0x8f, 0xa1, 0x01, + 0x80, 0x40, 0xa8, 0x06, 0x05, 0x80, 0x8a, 0x80, + 0xa2, 0x00, 0x80, 0xae, 0x80, 0xac, 0x81, 0xc2, + 0x80, 0x94, 0x82, 0x42, 0x00, 0x80, 0x40, 0xe1, + 0x80, 0x40, 0x94, 0x84, 0x44, 0x04, 0x28, 0xa9, + 0x80, 0x88, 0x42, 0x45, 0x10, 0x0c, 0x83, 0xa7, + 0x13, 0x80, 0x40, 0xa4, 0x81, 0x42, 0x3c, 0x83, + 0x41, 0x82, 0x81, 0x40, 0x98, 0x8a, 0xb0, 0x83, + 0xfa, 0x80, 0xb5, 0x8e, 0xa8, 0x01, 0x81, 0x89, + 0x82, 0xb0, 0x19, 0x09, 0x03, 0x80, 0x89, 0x80, + 0xb1, 0x82, 0xa3, 0x20, 0x87, 0xbd, 0x80, 0x8b, + 0x81, 0xb3, 0x88, 0x89, 0x19, 0x80, 0xde, 0x11, + 0x00, 0x0d, 0x80, 0x40, 0x9f, 0x02, 0x87, 0x94, + 0x81, 0xb8, 0x0a, 0x80, 0xa4, 0x32, 0x84, 0x40, + 0xc2, 0x39, 0x10, 0x80, 0x96, 0x80, 0xd3, 0x28, + 0x03, 0x08, 0x81, 0x40, 0xed, 0x1d, 0x08, 0x81, + 0x9a, 0x81, 0xd4, 0x39, 0x00, 0x81, 0xe9, 0x00, + 0x01, 0x28, 0x80, 0xe4, 0x11, 0x18, 0x84, 0x41, + 0x02, 0x88, 0x01, 0x40, 0xff, 0x08, 0x03, 0x80, + 0x40, 0x8f, 0x19, 0x0b, 0x80, 0x9f, 0x89, 0xa7, + 0x29, 0x1f, 0x80, 0x88, 0x29, 0x82, 0xad, 0x8c, + 0x01, 0x41, 0x95, 0x30, 0x28, 0x80, 0xd1, 0x95, + 0x0e, 0x01, 0x01, 0xf9, 0x2a, 0x00, 0x08, 0x30, + 0x80, 0xc7, 0x0a, 0x00, 0x80, 0x41, 0x5a, 0x81, + 0x55, 0x3a, 0x88, 0x60, 0x36, 0xb6, 0x84, 0xba, + 0x86, 0x88, 0x83, 0x44, 0x0a, 0x80, 0xbe, 0x90, + 0xbf, 0x08, 0x81, 0x60, 0x40, 0x0a, 0x18, 0x30, + 0x81, 0x4c, 0x9d, 0x08, 0x83, 0x52, 0x5b, 0xad, + 0x81, 0x96, 0x42, 0x1f, 0x82, 0x88, 0x8f, 0x0e, + 0x9d, 0x83, 0x40, 0x93, 0x82, 0x47, 0xba, 0xb6, + 0x83, 0xb1, 0x38, 0x8d, 0x80, 0x95, 0x20, 0x8e, + 0x45, 0x4f, 0x30, 0x90, 0x0e, 0x01, 0x04, 0x41, + 0x04, 0x8d, 0x41, 0x6f, 0x80, 0xbc, 0x83, 0x45, + 0xdf, 0x86, 0xec, 0x87, 0x4a, 0xae, 0x84, 0x6c, + 0x0c, 0x00, 0x80, 0x9d, 0xdf, 0xff, 0x40, 0xef, +}; + +static const uint8_t unicode_prop_Case_Ignorable_index[69] = { + 0xbe, 0x05, 0x00, 0xfe, 0x07, 0x00, 0x52, 0x0a, + 0xa0, 0xc1, 0x0b, 0x00, 0x82, 0x0d, 0x00, 0x3f, + 0x10, 0x80, 0xd4, 0x17, 0x40, 0xcf, 0x1a, 0x20, + 0xf5, 0x1c, 0x00, 0x80, 0x20, 0x00, 0x16, 0xa0, + 0x00, 0xc6, 0xa8, 0x00, 0xc2, 0xaa, 0x60, 0x56, + 0xfe, 0x20, 0xb1, 0x07, 0x01, 0x82, 0x10, 0x21, + 0x02, 0x13, 0x21, 0xb8, 0x16, 0x61, 0x97, 0x1a, + 0x01, 0x37, 0x6b, 0x21, 0x8c, 0xd1, 0x01, 0xd7, + 0xe8, 0x41, 0xf0, 0x01, 0x0e, +}; + +static const uint8_t unicode_prop_ID_Start_table[1079] = { + 0xc0, 0x99, 0x85, 0x99, 0xae, 0x80, 0x89, 0x03, + 0x04, 0x96, 0x80, 0x9e, 0x80, 0x41, 0xc9, 0x83, + 0x8b, 0x8d, 0x26, 0x00, 0x80, 0x40, 0x80, 0x20, + 0x09, 0x18, 0x05, 0x00, 0x10, 0x00, 0x93, 0x80, + 0xd2, 0x80, 0x40, 0x8a, 0x87, 0x40, 0xa5, 0x80, + 0xa5, 0x08, 0x85, 0xa8, 0xc6, 0x9a, 0x1b, 0xac, + 0xaa, 0xa2, 0x08, 0xe2, 0x00, 0x8e, 0x0e, 0x81, + 0x89, 0x11, 0x80, 0x8f, 0x00, 0x9d, 0x9c, 0xd8, + 0x8a, 0x80, 0x97, 0xa0, 0x88, 0x0b, 0x04, 0x95, + 0x18, 0x88, 0x02, 0x80, 0x96, 0x98, 0x86, 0x8a, + 0x84, 0x97, 0x05, 0x90, 0xa9, 0xb9, 0xb5, 0x10, + 0x91, 0x06, 0x89, 0x8e, 0x8f, 0x1f, 0x09, 0x81, + 0x95, 0x06, 0x00, 0x13, 0x10, 0x8f, 0x80, 0x8c, + 0x08, 0x82, 0x8d, 0x81, 0x89, 0x07, 0x2b, 0x09, + 0x95, 0x06, 0x01, 0x01, 0x01, 0x9e, 0x18, 0x80, + 0x92, 0x82, 0x8f, 0x88, 0x02, 0x80, 0x95, 0x06, + 0x01, 0x04, 0x10, 0x91, 0x80, 0x8e, 0x81, 0x96, + 0x80, 0x8a, 0x39, 0x09, 0x95, 0x06, 0x01, 0x04, + 0x10, 0x9d, 0x08, 0x82, 0x8e, 0x80, 0x90, 0x00, + 0x2a, 0x10, 0x1a, 0x08, 0x00, 0x0a, 0x0a, 0x12, + 0x8b, 0x95, 0x80, 0xb3, 0x38, 0x10, 0x96, 0x80, + 0x8f, 0x10, 0x99, 0x11, 0x01, 0x81, 0x9d, 0x03, + 0x38, 0x10, 0x96, 0x80, 0x89, 0x04, 0x10, 0x9e, + 0x08, 0x81, 0x8e, 0x81, 0x90, 0x88, 0x02, 0x80, + 0xa8, 0x08, 0x8f, 0x04, 0x17, 0x82, 0x97, 0x2c, + 0x91, 0x82, 0x97, 0x80, 0x88, 0x00, 0x0e, 0xb9, + 0xaf, 0x01, 0x8b, 0x86, 0xb9, 0x08, 0x00, 0x20, + 0x97, 0x00, 0x80, 0x89, 0x01, 0x88, 0x01, 0x20, + 0x80, 0x94, 0x83, 0x9f, 0x80, 0xbe, 0x38, 0xa3, + 0x9a, 0x84, 0xf2, 0xaa, 0x93, 0x80, 0x8f, 0x2b, + 0x1a, 0x02, 0x0e, 0x13, 0x8c, 0x8b, 0x80, 0x90, + 0xa5, 0x00, 0x20, 0x81, 0xaa, 0x80, 0x41, 0x4c, + 0x03, 0x0e, 0x00, 0x03, 0x81, 0xa8, 0x03, 0x81, + 0xa0, 0x03, 0x0e, 0x00, 0x03, 0x81, 0x8e, 0x80, + 0xb8, 0x03, 0x81, 0xc2, 0xa4, 0x8f, 0x8f, 0xd5, + 0x0d, 0x82, 0x42, 0x6b, 0x81, 0x90, 0x80, 0x99, + 0x84, 0xca, 0x82, 0x8a, 0x86, 0x91, 0x8c, 0x92, + 0x8d, 0x91, 0x8d, 0x8c, 0x02, 0x8e, 0xb3, 0xa2, + 0x03, 0x80, 0xc2, 0xd8, 0x86, 0xa8, 0x00, 0x84, + 0xc5, 0x89, 0x9e, 0xb0, 0x9d, 0x0c, 0x8a, 0xab, + 0x83, 0x99, 0xb5, 0x96, 0x88, 0xb4, 0xd1, 0x80, + 0xdc, 0xae, 0x90, 0x87, 0xb5, 0x9d, 0x8c, 0x81, + 0x89, 0xab, 0x99, 0xa3, 0xa8, 0x82, 0x89, 0xa3, + 0x81, 0x88, 0x86, 0xaa, 0x0a, 0xa8, 0x18, 0x28, + 0x0a, 0x04, 0x40, 0xbf, 0xbf, 0x41, 0x15, 0x0d, + 0x81, 0xa5, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x80, + 0x9e, 0x81, 0xb4, 0x06, 0x00, 0x12, 0x06, 0x13, + 0x0d, 0x83, 0x8c, 0x22, 0x06, 0xf3, 0x80, 0x8c, + 0x80, 0x8f, 0x8c, 0xe4, 0x03, 0x01, 0x89, 0x00, + 0x0d, 0x28, 0x00, 0x00, 0x80, 0x8f, 0x0b, 0x24, + 0x18, 0x90, 0xa8, 0x4a, 0x76, 0x40, 0xe4, 0x2b, + 0x11, 0x8b, 0xa5, 0x00, 0x20, 0x81, 0xb7, 0x30, + 0x8f, 0x96, 0x88, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x86, 0x42, 0x25, 0x82, 0x98, 0x88, + 0x34, 0x0c, 0x83, 0xd5, 0x1c, 0x80, 0xd9, 0x03, + 0x84, 0xaa, 0x80, 0xdd, 0x90, 0x9f, 0xaf, 0x8f, + 0x41, 0xff, 0x59, 0xbf, 0xbf, 0x60, 0x56, 0x8c, + 0xc2, 0xad, 0x81, 0x41, 0x0c, 0x82, 0x8f, 0x89, + 0x81, 0x93, 0xae, 0x8f, 0x9e, 0x81, 0xcf, 0xa6, + 0x88, 0x81, 0xe6, 0x81, 0xbf, 0x21, 0x00, 0x04, + 0x97, 0x8f, 0x02, 0x03, 0x80, 0x96, 0x9c, 0xb3, + 0x8d, 0xb1, 0xbd, 0x2a, 0x00, 0x81, 0x8a, 0x9b, + 0x89, 0x96, 0x98, 0x9c, 0x86, 0xae, 0x9b, 0x80, + 0x8f, 0x20, 0x89, 0x89, 0x20, 0xa8, 0x96, 0x10, + 0x87, 0x93, 0x96, 0x10, 0x82, 0xb1, 0x00, 0x11, + 0x0c, 0x08, 0x00, 0x97, 0x11, 0x8a, 0x32, 0x8b, + 0x29, 0x29, 0x85, 0x88, 0x30, 0x30, 0xaa, 0x80, + 0x8d, 0x85, 0xf2, 0x9c, 0x60, 0x2b, 0xa3, 0x8b, + 0x96, 0x83, 0xb0, 0x60, 0x21, 0x03, 0x41, 0x6d, + 0x81, 0xe9, 0xa5, 0x86, 0x8b, 0x24, 0x00, 0x89, + 0x80, 0x8c, 0x04, 0x00, 0x01, 0x01, 0x80, 0xeb, + 0xa0, 0x41, 0x6a, 0x91, 0xbf, 0x81, 0xb5, 0xa7, + 0x8b, 0xf3, 0x20, 0x40, 0x86, 0xa3, 0x99, 0x85, + 0x99, 0x8a, 0xd8, 0x15, 0x0d, 0x0d, 0x0a, 0xa2, + 0x8b, 0x80, 0x99, 0x80, 0x92, 0x01, 0x80, 0x8e, + 0x81, 0x8d, 0xa1, 0xfa, 0xc4, 0xb4, 0x41, 0x0a, + 0x9c, 0x82, 0xb0, 0xae, 0x9f, 0x8c, 0x9d, 0x84, + 0xa5, 0x89, 0x9d, 0x81, 0xa3, 0x1f, 0x04, 0xa9, + 0x40, 0x9d, 0x91, 0xa3, 0x83, 0xa3, 0x83, 0xa7, + 0x87, 0xb3, 0x8b, 0x8a, 0x80, 0x8e, 0x06, 0x01, + 0x80, 0x8a, 0x80, 0x8e, 0x06, 0x01, 0xc2, 0x41, + 0x36, 0x88, 0x95, 0x89, 0x87, 0x97, 0x28, 0xa9, + 0x80, 0x88, 0xc4, 0x29, 0x00, 0xab, 0x01, 0x10, + 0x81, 0x96, 0x89, 0x96, 0x88, 0x9e, 0xc0, 0x92, + 0x01, 0x89, 0x95, 0x89, 0x99, 0xc5, 0xb7, 0x29, + 0xbf, 0x80, 0x8e, 0x18, 0x10, 0x9c, 0xa9, 0x9c, + 0x82, 0x9c, 0xa2, 0x38, 0x9b, 0x9a, 0xb5, 0x89, + 0x95, 0x89, 0x92, 0x8c, 0x91, 0xed, 0xc8, 0xb6, + 0xb2, 0x8c, 0xb2, 0x8c, 0xa3, 0x41, 0x5b, 0xa9, + 0x29, 0xcd, 0x9c, 0x89, 0x07, 0x95, 0xa9, 0x91, + 0xad, 0x94, 0x9a, 0x96, 0x8b, 0xb4, 0xb8, 0x09, + 0x80, 0x8c, 0xac, 0x9f, 0x98, 0x99, 0xa3, 0x9c, + 0x01, 0x07, 0xa2, 0x10, 0x8b, 0xaf, 0x8d, 0x83, + 0x94, 0x00, 0x80, 0xa2, 0x91, 0x80, 0x98, 0xd3, + 0x30, 0x00, 0x18, 0x8e, 0x80, 0x89, 0x86, 0xae, + 0xa5, 0x39, 0x09, 0x95, 0x06, 0x01, 0x04, 0x10, + 0x91, 0x80, 0x8b, 0x84, 0x40, 0x9d, 0xb4, 0x91, + 0x83, 0x93, 0x82, 0x9d, 0xaf, 0x93, 0x08, 0x80, + 0x40, 0xb7, 0xae, 0xa8, 0x83, 0xa3, 0xaf, 0x93, + 0x80, 0xba, 0xaa, 0x8c, 0x80, 0xc6, 0x9a, 0xa4, + 0x86, 0x40, 0xb8, 0xab, 0xf3, 0xbf, 0x9e, 0x39, + 0x01, 0x38, 0x08, 0x97, 0x8e, 0x00, 0x80, 0xdd, + 0x39, 0xa6, 0x8f, 0x00, 0x80, 0x9b, 0x80, 0x89, + 0xa7, 0x30, 0x94, 0x80, 0x8a, 0xad, 0x92, 0x80, + 0x91, 0xc8, 0x41, 0x06, 0x88, 0x80, 0xa4, 0x90, + 0x80, 0xb0, 0x9d, 0xef, 0x30, 0x08, 0xa5, 0x94, + 0x80, 0x98, 0x28, 0x08, 0x9f, 0x8d, 0x80, 0x41, + 0x46, 0x92, 0x40, 0xbc, 0x80, 0xce, 0x43, 0x99, + 0xe5, 0xee, 0x90, 0x40, 0xc3, 0x4a, 0x4b, 0xe0, + 0x8e, 0x44, 0x2e, 0x4f, 0xd0, 0x42, 0x46, 0x60, + 0x21, 0xb8, 0x42, 0x38, 0x86, 0x9e, 0x90, 0xce, + 0x90, 0x9d, 0x91, 0xaf, 0x8f, 0x83, 0x9e, 0x94, + 0x84, 0x92, 0x42, 0xaf, 0xbf, 0xff, 0xca, 0x20, + 0xc1, 0x8c, 0xbf, 0x08, 0x80, 0x9b, 0x57, 0xf7, + 0x87, 0x44, 0xd5, 0xa9, 0x88, 0x60, 0x22, 0xe6, + 0x18, 0x30, 0x08, 0x41, 0x22, 0xac, 0x82, 0x90, + 0x1f, 0x41, 0x8b, 0x49, 0x03, 0xea, 0x84, 0x8c, + 0x82, 0x88, 0x86, 0x89, 0x57, 0x65, 0xd4, 0x80, + 0xc6, 0x01, 0x08, 0x09, 0x0b, 0x80, 0x8b, 0x00, + 0x06, 0x80, 0xc0, 0x03, 0x0f, 0x06, 0x80, 0x9b, + 0x03, 0x04, 0x00, 0x16, 0x80, 0x41, 0x53, 0x81, + 0x98, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, + 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, + 0x9e, 0x80, 0x98, 0x07, 0x47, 0x33, 0x9e, 0x41, + 0xe0, 0xac, 0x89, 0x86, 0x8f, 0x80, 0x41, 0x40, + 0x9d, 0x91, 0xab, 0x44, 0xf3, 0x30, 0x18, 0x08, + 0x8e, 0x80, 0x40, 0xc4, 0xba, 0xc3, 0x30, 0x44, + 0xb3, 0x18, 0x9a, 0x01, 0x00, 0x08, 0x80, 0x89, + 0x03, 0x00, 0x00, 0x28, 0x18, 0x00, 0x00, 0x02, + 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x0b, 0x06, 0x03, 0x03, 0x00, 0x80, 0x89, + 0x80, 0x90, 0x22, 0x04, 0x80, 0x90, 0x51, 0x43, + 0x60, 0xa6, 0xdf, 0x9f, 0x50, 0x38, 0x86, 0x40, + 0xdd, 0x81, 0x56, 0x81, 0x8d, 0x5d, 0x30, 0x4c, + 0x1e, 0x42, 0x1d, 0x45, 0xe1, 0x53, 0x4a, +}; + +static const uint8_t unicode_prop_ID_Start_index[102] = { + 0xf6, 0x03, 0x20, 0xa6, 0x07, 0x00, 0xa9, 0x09, + 0x20, 0xb1, 0x0a, 0x00, 0xba, 0x0b, 0x20, 0x3b, + 0x0d, 0x20, 0xc7, 0x0e, 0x20, 0x49, 0x12, 0x00, + 0x9b, 0x16, 0x00, 0xac, 0x19, 0x00, 0xc0, 0x1d, + 0x80, 0x80, 0x20, 0x20, 0x70, 0x2d, 0x00, 0x00, + 0x32, 0x00, 0xda, 0xa7, 0x00, 0x4c, 0xaa, 0x20, + 0xc7, 0xd7, 0x20, 0xfc, 0xfd, 0x20, 0x9d, 0x02, + 0x21, 0x96, 0x05, 0x01, 0xf3, 0x08, 0x01, 0xb3, + 0x0c, 0x21, 0x73, 0x11, 0x61, 0x3e, 0x13, 0x01, + 0x47, 0x17, 0x21, 0x9e, 0x1a, 0x01, 0x9a, 0x23, + 0x01, 0x78, 0x6b, 0x01, 0xfc, 0xb2, 0x61, 0x3a, + 0xd5, 0x01, 0x2d, 0xe1, 0x41, 0x33, 0xee, 0x01, + 0xe0, 0xa6, 0x62, 0x4b, 0x13, 0x03, +}; + +static const uint8_t unicode_prop_ID_Continue1_table[640] = { + 0xaf, 0x89, 0xa4, 0x80, 0xd6, 0x80, 0x42, 0x47, + 0xef, 0x96, 0x80, 0x40, 0xfa, 0x84, 0x41, 0x08, + 0xac, 0x00, 0x01, 0x01, 0x00, 0xc7, 0x8a, 0xaf, + 0x9e, 0x28, 0xe4, 0x31, 0x29, 0x08, 0x19, 0x89, + 0x96, 0x80, 0x9d, 0x9a, 0xda, 0x8a, 0x8e, 0x89, + 0xa0, 0x88, 0x88, 0x80, 0x97, 0x18, 0x88, 0x02, + 0x04, 0xaa, 0x82, 0xbb, 0x87, 0xa9, 0x97, 0x80, + 0xa0, 0xb5, 0x10, 0x91, 0x06, 0x89, 0x09, 0x89, + 0x90, 0x82, 0xb7, 0x00, 0x31, 0x09, 0x82, 0x88, + 0x80, 0x89, 0x09, 0x89, 0x8d, 0x01, 0x82, 0xb7, + 0x00, 0x23, 0x09, 0x12, 0x80, 0x93, 0x8b, 0x10, + 0x8a, 0x82, 0xb7, 0x00, 0x38, 0x10, 0x82, 0x93, + 0x09, 0x89, 0x89, 0x28, 0x82, 0xb7, 0x00, 0x31, + 0x09, 0x16, 0x82, 0x89, 0x09, 0x89, 0x91, 0x80, + 0xba, 0x22, 0x10, 0x83, 0x88, 0x80, 0x8d, 0x89, + 0x8f, 0x84, 0xb6, 0x00, 0x30, 0x10, 0x1e, 0x81, + 0x8a, 0x09, 0x89, 0x90, 0x82, 0xb7, 0x00, 0x30, + 0x10, 0x1e, 0x81, 0x8a, 0x09, 0x89, 0x8f, 0x83, + 0xb6, 0x08, 0x30, 0x10, 0x83, 0x88, 0x80, 0x89, + 0x09, 0x89, 0x90, 0x82, 0xc5, 0x03, 0x28, 0x00, + 0x3d, 0x89, 0x09, 0xbc, 0x01, 0x86, 0x8b, 0x38, + 0x89, 0xd6, 0x01, 0x88, 0x8a, 0x29, 0x89, 0xbd, + 0x0d, 0x89, 0x8a, 0x00, 0x00, 0x03, 0x81, 0xb0, + 0x93, 0x01, 0x84, 0x8a, 0x80, 0xa3, 0x88, 0x80, + 0xe3, 0x93, 0x80, 0x89, 0x8b, 0x1b, 0x10, 0x11, + 0x32, 0x83, 0x8c, 0x8b, 0x80, 0x8e, 0x42, 0xbe, + 0x82, 0x88, 0x88, 0x43, 0x9f, 0x83, 0x9b, 0x82, + 0x9c, 0x81, 0x9d, 0x81, 0xbf, 0x9f, 0x88, 0x01, + 0x89, 0xa0, 0x10, 0x8a, 0x40, 0x8e, 0x80, 0xf5, + 0x8b, 0x83, 0x8b, 0x89, 0x89, 0xff, 0x8a, 0xbb, + 0x84, 0xb8, 0x89, 0x80, 0x9c, 0x81, 0x8a, 0x85, + 0x89, 0x95, 0x8d, 0x80, 0x8f, 0xb0, 0x84, 0xae, + 0x90, 0x8a, 0x89, 0x90, 0x88, 0x8b, 0x82, 0x9d, + 0x8c, 0x81, 0x89, 0xab, 0x8d, 0xaf, 0x93, 0x87, + 0x89, 0x85, 0x89, 0xf5, 0x10, 0x94, 0x18, 0x28, + 0x0a, 0x40, 0xc5, 0xbf, 0x42, 0x3e, 0x81, 0x92, + 0x80, 0xfa, 0x8c, 0x18, 0x82, 0x8b, 0x4b, 0xfd, + 0x82, 0x40, 0x8c, 0x80, 0xdf, 0x9f, 0x42, 0x29, + 0x85, 0xe8, 0x81, 0x60, 0x75, 0x84, 0x89, 0xc4, + 0x03, 0x89, 0x9f, 0x81, 0xcf, 0x81, 0x41, 0x0f, + 0x02, 0x03, 0x80, 0x96, 0x23, 0x80, 0xd2, 0x81, + 0xb1, 0x91, 0x89, 0x89, 0x85, 0x91, 0x8c, 0x8a, + 0x9b, 0x87, 0x98, 0x8c, 0xab, 0x83, 0xae, 0x8d, + 0x8e, 0x89, 0x8a, 0x80, 0x89, 0x89, 0xae, 0x8d, + 0x8b, 0x07, 0x09, 0x89, 0xa0, 0x82, 0xb1, 0x00, + 0x11, 0x0c, 0x08, 0x80, 0xa8, 0x24, 0x81, 0x40, + 0xeb, 0x38, 0x09, 0x89, 0x60, 0x4f, 0x23, 0x80, + 0x42, 0xe0, 0x8f, 0x8f, 0x8f, 0x11, 0x97, 0x82, + 0x40, 0xbf, 0x89, 0xa4, 0x80, 0x42, 0xbc, 0x80, + 0x40, 0xe1, 0x80, 0x40, 0x94, 0x84, 0x41, 0x24, + 0x89, 0x45, 0x56, 0x10, 0x0c, 0x83, 0xa7, 0x13, + 0x80, 0x40, 0xa4, 0x81, 0x42, 0x3c, 0x1f, 0x89, + 0x41, 0x70, 0x81, 0x40, 0x98, 0x8a, 0xb0, 0x83, + 0xf9, 0x82, 0xb4, 0x8e, 0x9e, 0x8a, 0x09, 0x89, + 0x83, 0xac, 0x8a, 0x30, 0xac, 0x89, 0x2a, 0xa3, + 0x8d, 0x80, 0x89, 0x21, 0xab, 0x80, 0x8b, 0x82, + 0xaf, 0x8d, 0x3b, 0x80, 0x8b, 0xd1, 0x8b, 0x28, + 0x40, 0x9f, 0x8b, 0x84, 0x89, 0x2b, 0xb6, 0x08, + 0x31, 0x09, 0x82, 0x88, 0x80, 0x89, 0x09, 0x32, + 0x84, 0x40, 0xbf, 0x91, 0x88, 0x89, 0x18, 0xd0, + 0x93, 0x8b, 0x89, 0x40, 0xd4, 0x31, 0x88, 0x9a, + 0x81, 0xd1, 0x90, 0x8e, 0x89, 0xd0, 0x8c, 0x87, + 0x89, 0xd2, 0x8e, 0x83, 0x89, 0x40, 0xf1, 0x8e, + 0x40, 0xa4, 0x89, 0xc5, 0x28, 0x09, 0x18, 0x00, + 0x81, 0x8b, 0x89, 0xf6, 0x31, 0x32, 0x80, 0x9b, + 0x89, 0xa7, 0x30, 0x1f, 0x80, 0x88, 0x8a, 0xad, + 0x8f, 0x41, 0x94, 0x38, 0x87, 0x8f, 0x89, 0xb7, + 0x95, 0x80, 0x8d, 0xf9, 0x2a, 0x00, 0x08, 0x30, + 0x07, 0x89, 0xaf, 0x20, 0x08, 0x27, 0x89, 0x41, + 0x48, 0x83, 0x60, 0x4b, 0x68, 0x89, 0xd5, 0x89, + 0xa5, 0x84, 0xba, 0x86, 0x98, 0x89, 0x43, 0xf4, + 0x00, 0xb6, 0x33, 0xd0, 0x80, 0x8a, 0x81, 0x60, + 0x4c, 0xaa, 0x81, 0x52, 0x60, 0xad, 0x81, 0x96, + 0x42, 0x1d, 0x22, 0x2f, 0x39, 0x86, 0x9d, 0x83, + 0x40, 0x93, 0x82, 0x45, 0x88, 0xb1, 0x41, 0xff, + 0xb6, 0x83, 0xb1, 0x38, 0x8d, 0x80, 0x95, 0x20, + 0x8e, 0x45, 0x4f, 0x30, 0x90, 0x0e, 0x01, 0x04, + 0x41, 0x04, 0x86, 0x88, 0x89, 0x41, 0x63, 0x80, + 0xbc, 0x8d, 0x45, 0xd5, 0x86, 0xec, 0x34, 0x89, + 0x52, 0x95, 0x89, 0x6c, 0x05, 0x05, 0x40, 0xef, +}; + +static const uint8_t unicode_prop_ID_Continue1_index[60] = { + 0xfa, 0x06, 0x00, 0x70, 0x09, 0x00, 0xf0, 0x0a, + 0x40, 0x57, 0x0c, 0x00, 0xf0, 0x0d, 0x40, 0xc7, + 0x0f, 0x00, 0xea, 0x17, 0x20, 0x45, 0x1b, 0x20, + 0x55, 0x20, 0x20, 0x0c, 0xa8, 0x60, 0x37, 0xaa, + 0x00, 0x50, 0xfe, 0x00, 0x3a, 0x0d, 0x01, 0x83, + 0x11, 0x01, 0xc4, 0x14, 0x21, 0x44, 0x19, 0x21, + 0x5a, 0x1d, 0x41, 0x9f, 0xbc, 0x61, 0xb0, 0xda, + 0x21, 0xf0, 0x01, 0x0e, +}; + +#ifdef CONFIG_ALL_UNICODE + +static const uint8_t unicode_cc_table[881] = { + 0xb2, 0xcf, 0xd4, 0x00, 0xe8, 0x03, 0xdc, 0x00, + 0xe8, 0x00, 0xd8, 0x04, 0xdc, 0x01, 0xca, 0x03, + 0xdc, 0x01, 0xca, 0x0a, 0xdc, 0x04, 0x01, 0x03, + 0xdc, 0xc7, 0x00, 0xf0, 0xc0, 0x02, 0xdc, 0xc2, + 0x01, 0xdc, 0x80, 0xc2, 0x03, 0xdc, 0xc0, 0x00, + 0xe8, 0x01, 0xdc, 0xc0, 0x41, 0xe9, 0x00, 0xea, + 0x41, 0xe9, 0x00, 0xea, 0x00, 0xe9, 0xcc, 0xb0, + 0xe2, 0xc4, 0xb0, 0xd8, 0x00, 0xdc, 0xc3, 0x00, + 0xdc, 0xc2, 0x00, 0xde, 0x00, 0xdc, 0xc5, 0x05, + 0xdc, 0xc1, 0x00, 0xdc, 0xc1, 0x00, 0xde, 0x00, + 0xe4, 0xc0, 0x49, 0x0a, 0x43, 0x13, 0x80, 0x00, + 0x17, 0x80, 0x41, 0x18, 0x80, 0xc0, 0x00, 0xdc, + 0x80, 0x00, 0x12, 0xb0, 0x17, 0xc7, 0x42, 0x1e, + 0xaf, 0x47, 0x1b, 0xc1, 0x01, 0xdc, 0xc4, 0x00, + 0xdc, 0xc1, 0x00, 0xdc, 0x8f, 0x00, 0x23, 0xb0, + 0x34, 0xc6, 0x81, 0xc3, 0x00, 0xdc, 0xc0, 0x81, + 0xc1, 0x80, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0xa2, + 0x00, 0x24, 0x9d, 0xc0, 0x00, 0xdc, 0xc1, 0x00, + 0xdc, 0xc1, 0x02, 0xdc, 0xc0, 0x01, 0xdc, 0xc0, + 0x00, 0xdc, 0xc2, 0x00, 0xdc, 0xc0, 0x00, 0xdc, + 0xc0, 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xc1, 0xb0, + 0x6f, 0xc6, 0x00, 0xdc, 0xc0, 0x88, 0x00, 0xdc, + 0x97, 0xc3, 0x80, 0xc8, 0x80, 0xc2, 0x80, 0xc4, + 0xaa, 0x02, 0xdc, 0xb0, 0x0b, 0xc0, 0x02, 0xdc, + 0xc3, 0xa9, 0xc4, 0x04, 0xdc, 0xcd, 0x80, 0x00, + 0xdc, 0xc1, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0xc2, + 0x02, 0xdc, 0x42, 0x1b, 0xc2, 0x00, 0xdc, 0xc1, + 0x01, 0xdc, 0xc4, 0xb0, 0x0b, 0x00, 0x07, 0x8f, + 0x00, 0x09, 0x82, 0xc0, 0x00, 0xdc, 0xc1, 0xb0, + 0x36, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xaf, 0xc0, + 0xb0, 0x0c, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, + 0x3d, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x3d, + 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x4e, 0x00, + 0x09, 0xb0, 0x3d, 0x00, 0x07, 0x8f, 0x00, 0x09, + 0x86, 0x00, 0x54, 0x00, 0x5b, 0xb0, 0x34, 0x00, + 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x3c, 0x01, 0x09, + 0x8f, 0x00, 0x09, 0xb0, 0x4b, 0x00, 0x09, 0xb0, + 0x3c, 0x01, 0x67, 0x00, 0x09, 0x8c, 0x03, 0x6b, + 0xb0, 0x3b, 0x01, 0x76, 0x00, 0x09, 0x8c, 0x03, + 0x7a, 0xb0, 0x1b, 0x01, 0xdc, 0x9a, 0x00, 0xdc, + 0x80, 0x00, 0xdc, 0x80, 0x00, 0xd8, 0xb0, 0x06, + 0x41, 0x81, 0x80, 0x00, 0x84, 0x84, 0x03, 0x82, + 0x81, 0x00, 0x82, 0x80, 0xc1, 0x00, 0x09, 0x80, + 0xc1, 0xb0, 0x0d, 0x00, 0xdc, 0xb0, 0x3f, 0x00, + 0x07, 0x80, 0x01, 0x09, 0xb0, 0x21, 0x00, 0xdc, + 0xb2, 0x9e, 0xc2, 0xb3, 0x83, 0x01, 0x09, 0x9d, + 0x00, 0x09, 0xb0, 0x6c, 0x00, 0x09, 0x89, 0xc0, + 0xb0, 0x9a, 0x00, 0xe4, 0xb0, 0x5e, 0x00, 0xde, + 0xc0, 0x00, 0xdc, 0xb0, 0xaa, 0xc0, 0x00, 0xdc, + 0xb0, 0x16, 0x00, 0x09, 0x93, 0xc7, 0x81, 0x00, + 0xdc, 0xaf, 0xc4, 0x05, 0xdc, 0xc1, 0x00, 0xdc, + 0x80, 0x01, 0xdc, 0xc1, 0x01, 0xdc, 0xc4, 0x00, + 0xdc, 0xc3, 0xb0, 0x34, 0x00, 0x07, 0x8e, 0x00, + 0x09, 0xa5, 0xc0, 0x00, 0xdc, 0xc6, 0xb0, 0x05, + 0x01, 0x09, 0xb0, 0x09, 0x00, 0x07, 0x8a, 0x01, + 0x09, 0xb0, 0x12, 0x00, 0x07, 0xb0, 0x67, 0xc2, + 0x41, 0x00, 0x04, 0xdc, 0xc1, 0x03, 0xdc, 0xc0, + 0x41, 0x00, 0x05, 0x01, 0x83, 0x00, 0xdc, 0x85, + 0xc0, 0x82, 0xc1, 0xb0, 0x95, 0xc1, 0x00, 0xdc, + 0xc6, 0x00, 0xdc, 0xc1, 0x00, 0xea, 0x00, 0xd6, + 0x00, 0xdc, 0x00, 0xca, 0xe4, 0x00, 0xe8, 0x01, + 0xe4, 0x00, 0xdc, 0x00, 0xda, 0xc0, 0x00, 0xe9, + 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xb2, 0x9f, 0xc1, + 0x01, 0x01, 0xc3, 0x02, 0x01, 0xc1, 0x83, 0xc0, + 0x82, 0x01, 0x01, 0xc0, 0x00, 0xdc, 0xc0, 0x01, + 0x01, 0x03, 0xdc, 0xc0, 0xb8, 0x03, 0xcd, 0xc2, + 0xb0, 0x5c, 0x00, 0x09, 0xb0, 0x2f, 0xdf, 0xb1, + 0xf9, 0x00, 0xda, 0x00, 0xe4, 0x00, 0xe8, 0x00, + 0xde, 0x01, 0xe0, 0xb0, 0x38, 0x01, 0x08, 0xb8, + 0x6d, 0xa3, 0xc0, 0x83, 0xc9, 0x9f, 0xc1, 0xb0, + 0x1f, 0xc1, 0xb0, 0xe3, 0x00, 0x09, 0xa4, 0x00, + 0x09, 0xb0, 0x66, 0x00, 0x09, 0x9a, 0xd1, 0xb0, + 0x08, 0x02, 0xdc, 0xa4, 0x00, 0x09, 0xb0, 0x2e, + 0x00, 0x07, 0x8b, 0x00, 0x09, 0xb0, 0xbe, 0xc0, + 0x80, 0xc1, 0x00, 0xdc, 0x81, 0xc1, 0x84, 0xc1, + 0x80, 0xc0, 0xb0, 0x03, 0x00, 0x09, 0xb0, 0xc5, + 0x00, 0x09, 0xb8, 0x46, 0xff, 0x00, 0x1a, 0xb2, + 0xd0, 0xc6, 0x06, 0xdc, 0xc1, 0xb3, 0x9c, 0x00, + 0xdc, 0xb0, 0xb1, 0x00, 0xdc, 0xb0, 0x64, 0xc4, + 0xb6, 0x61, 0x00, 0xdc, 0x80, 0xc0, 0xa7, 0xc0, + 0x00, 0x01, 0x00, 0xdc, 0x83, 0x00, 0x09, 0xb0, + 0x74, 0xc0, 0x00, 0xdc, 0xb2, 0x0c, 0xc3, 0xb1, + 0x52, 0xc1, 0xb0, 0x68, 0x01, 0xdc, 0xc2, 0x00, + 0xdc, 0xc0, 0x03, 0xdc, 0xb0, 0x00, 0xc0, 0x00, + 0xdc, 0xc0, 0x00, 0xdc, 0xb0, 0x8f, 0x00, 0x09, + 0xa8, 0x00, 0x09, 0x8d, 0x00, 0x09, 0xb0, 0x08, + 0x00, 0x09, 0x00, 0x07, 0xb0, 0x14, 0xc2, 0xaf, + 0x01, 0x09, 0xb0, 0x0d, 0x00, 0x07, 0xb0, 0x1b, + 0x00, 0x09, 0x88, 0x00, 0x07, 0xb0, 0x39, 0x00, + 0x09, 0x00, 0x07, 0xb0, 0x81, 0x00, 0x07, 0x00, + 0x09, 0xb0, 0x1f, 0x01, 0x07, 0x8f, 0x00, 0x09, + 0x97, 0xc6, 0x82, 0xc4, 0xb0, 0x9c, 0x00, 0x09, + 0x82, 0x00, 0x07, 0x96, 0xc0, 0xb0, 0x32, 0x00, + 0x09, 0x00, 0x07, 0xb0, 0xca, 0x00, 0x09, 0x00, + 0x07, 0xb0, 0x4d, 0x00, 0x09, 0xb0, 0x45, 0x00, + 0x09, 0x00, 0x07, 0xb0, 0x42, 0x00, 0x09, 0xb0, + 0xdc, 0x00, 0x09, 0x00, 0x07, 0xb0, 0xd1, 0x01, + 0x09, 0x83, 0x00, 0x07, 0xb0, 0x6b, 0x00, 0x09, + 0xb0, 0x22, 0x00, 0x09, 0x91, 0x00, 0x09, 0xb0, + 0x20, 0x00, 0x09, 0xb1, 0x74, 0x00, 0x09, 0xb0, + 0xd1, 0x00, 0x07, 0x80, 0x01, 0x09, 0xb0, 0x20, + 0x00, 0x09, 0xb8, 0x45, 0x27, 0x04, 0x01, 0xb0, + 0x0a, 0xc6, 0xb4, 0x88, 0x01, 0x06, 0xb8, 0x44, + 0x7b, 0x00, 0x01, 0xb8, 0x0c, 0x95, 0x01, 0xd8, + 0x02, 0x01, 0x82, 0x00, 0xe2, 0x04, 0xd8, 0x87, + 0x07, 0xdc, 0x81, 0xc4, 0x01, 0xdc, 0x9d, 0xc3, + 0xb0, 0x63, 0xc2, 0xb8, 0x05, 0x8a, 0xc6, 0x80, + 0xd0, 0x81, 0xc6, 0x80, 0xc1, 0x80, 0xc4, 0xb0, + 0xd4, 0xc6, 0xb1, 0x46, 0xc0, 0xb0, 0x0c, 0xc3, + 0xb5, 0xaf, 0x06, 0xdc, 0xb0, 0x3c, 0xc5, 0x00, + 0x07, +}; + +static const uint8_t unicode_cc_index[84] = { + 0x4d, 0x03, 0x00, 0x97, 0x05, 0x20, 0xc6, 0x05, + 0x00, 0xe7, 0x06, 0x00, 0x45, 0x07, 0x00, 0x9c, + 0x08, 0x00, 0x4d, 0x09, 0x00, 0x3c, 0x0b, 0x00, + 0x3d, 0x0d, 0x00, 0x36, 0x0f, 0x00, 0x38, 0x10, + 0x20, 0x3a, 0x19, 0x00, 0xcb, 0x1a, 0x20, 0xd3, + 0x1c, 0x00, 0xcf, 0x1d, 0x00, 0xe2, 0x20, 0x00, + 0x2e, 0x30, 0x20, 0x2b, 0xa9, 0x20, 0xed, 0xab, + 0x00, 0x39, 0x0a, 0x01, 0x84, 0x0f, 0x21, 0xc0, + 0x11, 0x01, 0x43, 0x14, 0x01, 0x39, 0x18, 0x21, + 0x42, 0x1d, 0x21, 0x67, 0xd1, 0x01, 0x30, 0xe1, + 0x21, 0x4b, 0xe9, 0x01, +}; + +static const uint32_t unicode_decomp_table1[693] = { + 0x00280081, 0x002a0097, 0x002a8081, 0x002bc097, + 0x002c8115, 0x002d0097, 0x002d4081, 0x002e0097, + 0x002e4115, 0x002f0199, 0x00302016, 0x00400842, + 0x00448a42, 0x004a0442, 0x004c0096, 0x004c8117, + 0x004d0242, 0x004e4342, 0x004fc12f, 0x0050c342, + 0x005240bf, 0x00530342, 0x00550942, 0x005a0842, + 0x005e0096, 0x005e4342, 0x005fc081, 0x00680142, + 0x006bc142, 0x00710185, 0x0071c317, 0x00734844, + 0x00778344, 0x00798342, 0x007b02be, 0x007c4197, + 0x007d0142, 0x007e0444, 0x00800e42, 0x00878142, + 0x00898744, 0x00ac0483, 0x00b60317, 0x00b80283, + 0x00d00214, 0x00d10096, 0x00dd0080, 0x00de8097, + 0x00df8080, 0x00e10097, 0x00e1413e, 0x00e1c080, + 0x00e204be, 0x00ea83ae, 0x00f282ae, 0x00f401ad, + 0x00f4c12e, 0x00f54103, 0x00fc0303, 0x00fe4081, + 0x0100023e, 0x0101c0be, 0x010301be, 0x010640be, + 0x010e40be, 0x0114023e, 0x0115c0be, 0x011701be, + 0x011d8144, 0x01304144, 0x01340244, 0x01358144, + 0x01368344, 0x01388344, 0x013a8644, 0x013e0144, + 0x0161c085, 0x018882ae, 0x019d422f, 0x01b00184, + 0x01b4c084, 0x024a4084, 0x024c4084, 0x024d0084, + 0x0256042e, 0x0272c12e, 0x02770120, 0x0277c084, + 0x028cc084, 0x028d8084, 0x029641ae, 0x02978084, + 0x02d20084, 0x02d2c12e, 0x02d70120, 0x02e50084, + 0x02f281ae, 0x03120084, 0x03300084, 0x0331c122, + 0x0332812e, 0x035281ae, 0x03768084, 0x037701ae, + 0x038cc085, 0x03acc085, 0x03b7012f, 0x03c30081, + 0x03d0c084, 0x03d34084, 0x03d48084, 0x03d5c084, + 0x03d70084, 0x03da4084, 0x03dcc084, 0x03dd412e, + 0x03ddc085, 0x03de0084, 0x03de4085, 0x03e04084, + 0x03e4c084, 0x03e74084, 0x03e88084, 0x03e9c084, + 0x03eb0084, 0x03ee4084, 0x04098084, 0x043f0081, + 0x06c18484, 0x06c48084, 0x06cec184, 0x06d00120, + 0x06d0c084, 0x074b0383, 0x074cc41f, 0x074f1783, + 0x075e0081, 0x0766d283, 0x07801d44, 0x078e8942, + 0x07931844, 0x079f0d42, 0x07a58216, 0x07a68085, + 0x07a6c0be, 0x07a80d44, 0x07aea044, 0x07c00122, + 0x07c08344, 0x07c20122, 0x07c28344, 0x07c40122, + 0x07c48244, 0x07c60122, 0x07c68244, 0x07c8113e, + 0x07d08244, 0x07d20122, 0x07d28244, 0x07d40122, + 0x07d48344, 0x07d64c3e, 0x07dc4080, 0x07dc80be, + 0x07dcc080, 0x07dd00be, 0x07dd4080, 0x07dd80be, + 0x07ddc080, 0x07de00be, 0x07de4080, 0x07de80be, + 0x07dec080, 0x07df00be, 0x07df4080, 0x07e00820, + 0x07e40820, 0x07e80820, 0x07ec05be, 0x07eec080, + 0x07ef00be, 0x07ef4097, 0x07ef8080, 0x07efc117, + 0x07f0443e, 0x07f24080, 0x07f280be, 0x07f2c080, + 0x07f303be, 0x07f4c080, 0x07f582ae, 0x07f6c080, + 0x07f7433e, 0x07f8c080, 0x07f903ae, 0x07fac080, + 0x07fb013e, 0x07fb8102, 0x07fc83be, 0x07fe4080, + 0x07fe80be, 0x07fec080, 0x07ff00be, 0x07ff4080, + 0x07ff8097, 0x0800011e, 0x08008495, 0x08044081, + 0x0805c097, 0x08090081, 0x08094097, 0x08098099, + 0x080bc081, 0x080cc085, 0x080d00b1, 0x080d8085, + 0x080dc0b1, 0x080f0197, 0x0811c197, 0x0815c0b3, + 0x0817c081, 0x081c0595, 0x081ec081, 0x081f0215, + 0x0820051f, 0x08228583, 0x08254415, 0x082a0097, + 0x08400119, 0x08408081, 0x0840c0bf, 0x08414119, + 0x0841c081, 0x084240bf, 0x0842852d, 0x08454081, + 0x08458097, 0x08464295, 0x08480097, 0x08484099, + 0x08488097, 0x08490081, 0x08498080, 0x084a0081, + 0x084a8102, 0x084b0495, 0x084d421f, 0x084e4081, + 0x084ec099, 0x084f0283, 0x08514295, 0x08540119, + 0x0854809b, 0x0854c619, 0x0857c097, 0x08580081, + 0x08584097, 0x08588099, 0x0858c097, 0x08590081, + 0x08594097, 0x08598099, 0x0859c09b, 0x085a0097, + 0x085a4081, 0x085a8097, 0x085ac099, 0x085b0295, + 0x085c4097, 0x085c8099, 0x085cc097, 0x085d0081, + 0x085d4097, 0x085d8099, 0x085dc09b, 0x085e0097, + 0x085e4081, 0x085e8097, 0x085ec099, 0x085f0215, + 0x08624099, 0x0866813e, 0x086b80be, 0x087341be, + 0x088100be, 0x088240be, 0x088300be, 0x088901be, + 0x088b0085, 0x088b40b1, 0x088bc085, 0x088c00b1, + 0x089040be, 0x089100be, 0x0891c1be, 0x089801be, + 0x089b42be, 0x089d0144, 0x089e0144, 0x08a00144, + 0x08a10144, 0x08a20144, 0x08ab023e, 0x08b80244, + 0x08ba8220, 0x08ca411e, 0x0918049f, 0x091a4523, + 0x091cc097, 0x091d04a5, 0x091f452b, 0x0921c09b, + 0x092204a1, 0x09244525, 0x0926c099, 0x09270d25, + 0x092d8d1f, 0x09340d1f, 0x093a8081, 0x0a8300b3, + 0x0a9d0099, 0x0a9d4097, 0x0a9d8099, 0x0ab700be, + 0x0b1f0115, 0x0b5bc081, 0x0ba7c081, 0x0bbcc081, + 0x0bc004ad, 0x0bc244ad, 0x0bc484ad, 0x0bc6f383, + 0x0be0852d, 0x0be31d03, 0x0bf1882d, 0x0c000081, + 0x0c0d8283, 0x0c130b84, 0x0c194284, 0x0c1c0122, + 0x0c1cc122, 0x0c1d8122, 0x0c1e4122, 0x0c1f0122, + 0x0c250084, 0x0c26c123, 0x0c278084, 0x0c27c085, + 0x0c2b0b84, 0x0c314284, 0x0c340122, 0x0c34c122, + 0x0c358122, 0x0c364122, 0x0c370122, 0x0c3d0084, + 0x0c3dc220, 0x0c3f8084, 0x0c3fc085, 0x0c4c4a2d, + 0x0c51451f, 0x0c53ca9f, 0x0c5915ad, 0x0c648703, + 0x0c800741, 0x0c838089, 0x0c83c129, 0x0c8441a9, + 0x0c850089, 0x0c854129, 0x0c85c2a9, 0x0c870089, + 0x0c87408f, 0x0c87808d, 0x0c881241, 0x0c910203, + 0x0c940099, 0x0c9444a3, 0x0c968323, 0x0c98072d, + 0x0c9b84af, 0x0c9dc2a1, 0x0c9f00b5, 0x0c9f40b3, + 0x0c9f8085, 0x0ca01883, 0x0cac4223, 0x0cad4523, + 0x0cafc097, 0x0cb004a1, 0x0cb241a5, 0x0cb30097, + 0x0cb34099, 0x0cb38097, 0x0cb3c099, 0x0cb417ad, + 0x0cbfc085, 0x0cc001b3, 0x0cc0c0b1, 0x0cc100b3, + 0x0cc14131, 0x0cc1c0b5, 0x0cc200b3, 0x0cc241b1, + 0x0cc30133, 0x0cc38131, 0x0cc40085, 0x0cc440b1, + 0x0cc48133, 0x0cc50085, 0x0cc540b5, 0x0cc580b7, + 0x0cc5c0b5, 0x0cc600b1, 0x0cc64135, 0x0cc6c0b3, + 0x0cc701b1, 0x0cc7c0b3, 0x0cc800b5, 0x0cc840b3, + 0x0cc881b1, 0x0cc9422f, 0x0cca4131, 0x0ccac0b5, + 0x0ccb00b1, 0x0ccb40b3, 0x0ccb80b5, 0x0ccbc0b1, + 0x0ccc012f, 0x0ccc80b5, 0x0cccc0b3, 0x0ccd00b5, + 0x0ccd40b1, 0x0ccd80b5, 0x0ccdc085, 0x0cce02b1, + 0x0ccf40b3, 0x0ccf80b1, 0x0ccfc085, 0x0cd001b1, + 0x0cd0c0b3, 0x0cd101b1, 0x0cd1c0b5, 0x0cd200b3, + 0x0cd24085, 0x0cd280b5, 0x0cd2c085, 0x0cd30133, + 0x0cd381b1, 0x0cd440b3, 0x0cd48085, 0x0cd4c0b1, + 0x0cd500b3, 0x0cd54085, 0x0cd580b5, 0x0cd5c0b1, + 0x0cd60521, 0x0cd88525, 0x0cdb02a5, 0x0cdc4099, + 0x0cdc8117, 0x0cdd0099, 0x0cdd4197, 0x0cde0127, + 0x0cde8285, 0x0cdfc089, 0x0ce0043f, 0x0ce20099, + 0x0ce2409b, 0x0ce283bf, 0x0ce44219, 0x0ce54205, + 0x0ce6433f, 0x0ce7c131, 0x0ce84085, 0x0ce881b1, + 0x0ce94085, 0x0ce98107, 0x0cea0089, 0x0cea4097, + 0x0cea8219, 0x0ceb809d, 0x0cebc08d, 0x0cec083f, + 0x0cf00105, 0x0cf0809b, 0x0cf0c197, 0x0cf1809b, + 0x0cf1c099, 0x0cf20517, 0x0cf48099, 0x0cf4c117, + 0x0cf54119, 0x0cf5c097, 0x0cf6009b, 0x0cf64099, + 0x0cf68217, 0x0cf78119, 0x0cf804a1, 0x0cfa4525, + 0x0cfcc525, 0x0cff4125, 0x0cffc099, 0x29a70103, + 0x29dc0081, 0x29fc8195, 0x29fe0103, 0x2ad70203, + 0x2ada4081, 0x3e401482, 0x3e4a7f82, 0x3e6a3f82, + 0x3e8aa102, 0x3e9b0110, 0x3e9c2f82, 0x3eb3c590, + 0x3ec00197, 0x3ec0c119, 0x3ec1413f, 0x3ec4c2af, + 0x3ec74184, 0x3ec804ad, 0x3eca4081, 0x3eca8304, + 0x3ecc03a0, 0x3ece02a0, 0x3ecf8084, 0x3ed00120, + 0x3ed0c120, 0x3ed184ae, 0x3ed3c085, 0x3ed4312d, + 0x3ef4cbad, 0x3efa892f, 0x3eff022d, 0x3f002f2f, + 0x3f1782a5, 0x3f18c0b1, 0x3f1907af, 0x3f1cffaf, + 0x3f3c81a5, 0x3f3d64af, 0x3f542031, 0x3f649b31, + 0x3f7c0131, 0x3f7c83b3, 0x3f7e40b1, 0x3f7e80bd, + 0x3f7ec0bb, 0x3f7f00b3, 0x3f840503, 0x3f8c01ad, + 0x3f8cc315, 0x3f8e462d, 0x3f91cc03, 0x3f97c695, + 0x3f9c01af, 0x3f9d0085, 0x3f9d852f, 0x3fa03aad, + 0x3fbd442f, 0x3fc06f1f, 0x3fd7c11f, 0x3fd85fad, + 0x3fe80081, 0x3fe84f1f, 0x3ff0831f, 0x3ff2831f, + 0x3ff4831f, 0x3ff6819f, 0x3ff80783, 0x41e04d83, + 0x41e70f91, 0x44268192, 0x442ac092, 0x444b8112, + 0x44d2c112, 0x452ec212, 0x456e8112, 0x464e0092, + 0x74578392, 0x746ec312, 0x75000d1f, 0x75068d1f, + 0x750d0d1f, 0x7513839f, 0x7515891f, 0x751a0d1f, + 0x75208d1f, 0x75271015, 0x752f439f, 0x7531459f, + 0x75340d1f, 0x753a8d1f, 0x75410395, 0x7543441f, + 0x7545839f, 0x75478d1f, 0x754e0795, 0x7552839f, + 0x75548d1f, 0x755b0d1f, 0x75618d1f, 0x75680d1f, + 0x756e8d1f, 0x75750d1f, 0x757b8d1f, 0x75820d1f, + 0x75888d1f, 0x758f0d1f, 0x75958d1f, 0x759c0d1f, + 0x75a28d1f, 0x75a90103, 0x75aa089f, 0x75ae4081, + 0x75ae839f, 0x75b04081, 0x75b08c9f, 0x75b6c081, + 0x75b7032d, 0x75b8889f, 0x75bcc081, 0x75bd039f, + 0x75bec081, 0x75bf0c9f, 0x75c54081, 0x75c5832d, + 0x75c7089f, 0x75cb4081, 0x75cb839f, 0x75cd4081, + 0x75cd8c9f, 0x75d3c081, 0x75d4032d, 0x75d5889f, + 0x75d9c081, 0x75da039f, 0x75dbc081, 0x75dc0c9f, + 0x75e24081, 0x75e2832d, 0x75e4089f, 0x75e84081, + 0x75e8839f, 0x75ea4081, 0x75ea8c9f, 0x75f0c081, + 0x75f1042d, 0x75f3851f, 0x75f6051f, 0x75f8851f, + 0x75fb051f, 0x75fd851f, 0x7b80022d, 0x7b814dad, + 0x7b884203, 0x7b89c081, 0x7b8a452d, 0x7b8d0403, + 0x7b908081, 0x7b91dc03, 0x7ba0052d, 0x7ba2c8ad, + 0x7ba84483, 0x7baac8ad, 0x7c400097, 0x7c404521, + 0x7c440d25, 0x7c4a8087, 0x7c4ac115, 0x7c4b4117, + 0x7c4c0d1f, 0x7c528217, 0x7c538099, 0x7c53c097, + 0x7c5a8197, 0x7c640097, 0x7c80012f, 0x7c808081, + 0x7c841603, 0x7c9004c1, 0x7c940103, 0x7efc051f, + 0xbe0001ac, 0xbe00d110, 0xbe0947ac, 0xbe0d3910, + 0xbe29872c, 0xbe2d022c, 0xbe2e3790, 0xbe49ff90, + 0xbe69bc10, +}; + +static const uint16_t unicode_decomp_table2[693] = { + 0x0020, 0x0000, 0x0061, 0x0002, 0x0004, 0x0006, 0x03bc, 0x0008, + 0x000a, 0x000c, 0x0015, 0x0095, 0x00a5, 0x00b9, 0x00c1, 0x00c3, + 0x00c7, 0x00cb, 0x00d1, 0x00d7, 0x00dd, 0x00e0, 0x00e6, 0x00f8, + 0x0108, 0x010a, 0x0073, 0x0110, 0x0112, 0x0114, 0x0120, 0x012c, + 0x0144, 0x014d, 0x0153, 0x0162, 0x0168, 0x016a, 0x0176, 0x0192, + 0x0194, 0x01a9, 0x01bb, 0x01c7, 0x01d1, 0x01d5, 0x02b9, 0x01d7, + 0x003b, 0x01d9, 0x01db, 0x00b7, 0x01e1, 0x01fc, 0x020c, 0x0218, + 0x021d, 0x0223, 0x0227, 0x03a3, 0x0233, 0x023f, 0x0242, 0x024b, + 0x024e, 0x0251, 0x025d, 0x0260, 0x0269, 0x026c, 0x026f, 0x0275, + 0x0278, 0x0281, 0x028a, 0x029c, 0x029f, 0x02a3, 0x02af, 0x02b9, + 0x02c5, 0x02c9, 0x02cd, 0x02d1, 0x02d5, 0x02e7, 0x02ed, 0x02f1, + 0x02f5, 0x02f9, 0x02fd, 0x0305, 0x0309, 0x030d, 0x0313, 0x0317, + 0x031b, 0x0323, 0x0327, 0x032b, 0x032f, 0x0335, 0x033d, 0x0341, + 0x0349, 0x034d, 0x0351, 0x0f0b, 0x0357, 0x035b, 0x035f, 0x0363, + 0x0367, 0x036b, 0x036f, 0x0373, 0x0379, 0x037d, 0x0381, 0x0385, + 0x0389, 0x038d, 0x0391, 0x0395, 0x0399, 0x039d, 0x03a1, 0x10dc, + 0x03a5, 0x03c9, 0x03cd, 0x03d9, 0x03dd, 0x03e1, 0x03ef, 0x03f1, + 0x043d, 0x044f, 0x0499, 0x04f0, 0x0502, 0x054a, 0x0564, 0x056c, + 0x0570, 0x0573, 0x059a, 0x05fa, 0x05fe, 0x0607, 0x060b, 0x0614, + 0x0618, 0x061e, 0x0622, 0x0628, 0x068e, 0x0694, 0x0698, 0x069e, + 0x06a2, 0x06ab, 0x03ac, 0x06f3, 0x03ad, 0x06f6, 0x03ae, 0x06f9, + 0x03af, 0x06fc, 0x03cc, 0x06ff, 0x03cd, 0x0702, 0x03ce, 0x0705, + 0x0709, 0x070d, 0x0711, 0x0386, 0x0732, 0x0735, 0x03b9, 0x0737, + 0x073b, 0x0388, 0x0753, 0x0389, 0x0756, 0x0390, 0x076b, 0x038a, + 0x0777, 0x03b0, 0x0789, 0x038e, 0x0799, 0x079f, 0x07a3, 0x038c, + 0x07b8, 0x038f, 0x07bb, 0x00b4, 0x07be, 0x07c0, 0x07c2, 0x2010, + 0x07cb, 0x002e, 0x07cd, 0x07cf, 0x0020, 0x07d2, 0x07d6, 0x07db, + 0x07df, 0x07e4, 0x07ea, 0x07f0, 0x0020, 0x07f6, 0x2212, 0x0801, + 0x0805, 0x0807, 0x081d, 0x0825, 0x0827, 0x0043, 0x082d, 0x0830, + 0x0190, 0x0836, 0x0839, 0x004e, 0x0845, 0x0847, 0x084c, 0x084e, + 0x0851, 0x005a, 0x03a9, 0x005a, 0x0853, 0x0857, 0x0860, 0x0069, + 0x0862, 0x0865, 0x086f, 0x0874, 0x087a, 0x087e, 0x08a2, 0x0049, + 0x08a4, 0x08a6, 0x08a9, 0x0056, 0x08ab, 0x08ad, 0x08b0, 0x08b4, + 0x0058, 0x08b6, 0x08b8, 0x08bb, 0x08c0, 0x08c2, 0x08c5, 0x0076, + 0x08c7, 0x08c9, 0x08cc, 0x08d0, 0x0078, 0x08d2, 0x08d4, 0x08d7, + 0x08db, 0x08de, 0x08e4, 0x08e7, 0x08f0, 0x08f3, 0x08f6, 0x08f9, + 0x0902, 0x0906, 0x090b, 0x090f, 0x0914, 0x0917, 0x091a, 0x0923, + 0x092c, 0x093b, 0x093e, 0x0941, 0x0944, 0x0947, 0x094a, 0x0956, + 0x095c, 0x0960, 0x0962, 0x0964, 0x0968, 0x096a, 0x0970, 0x0978, + 0x097c, 0x0980, 0x0986, 0x0989, 0x098f, 0x0991, 0x0030, 0x0993, + 0x0999, 0x099c, 0x099e, 0x09a1, 0x09a4, 0x2d61, 0x6bcd, 0x9f9f, + 0x09a6, 0x09b1, 0x09bc, 0x09c7, 0x0a95, 0x0aa1, 0x0b15, 0x0020, + 0x0b27, 0x0b31, 0x0b8d, 0x0ba1, 0x0ba5, 0x0ba9, 0x0bad, 0x0bb1, + 0x0bb5, 0x0bb9, 0x0bbd, 0x0bc1, 0x0bc5, 0x0c21, 0x0c35, 0x0c39, + 0x0c3d, 0x0c41, 0x0c45, 0x0c49, 0x0c4d, 0x0c51, 0x0c55, 0x0c59, + 0x0c6f, 0x0c71, 0x0c73, 0x0ca0, 0x0cbc, 0x0cdc, 0x0ce4, 0x0cec, + 0x0cf4, 0x0cfc, 0x0d04, 0x0d0c, 0x0d14, 0x0d22, 0x0d2e, 0x0d7a, + 0x0d82, 0x0d85, 0x0d89, 0x0d8d, 0x0d9d, 0x0db1, 0x0db5, 0x0dbc, + 0x0dc2, 0x0dc6, 0x0e28, 0x0e2c, 0x0e30, 0x0e32, 0x0e36, 0x0e3c, + 0x0e3e, 0x0e41, 0x0e43, 0x0e46, 0x0e77, 0x0e7b, 0x0e89, 0x0e8e, + 0x0e94, 0x0e9c, 0x0ea3, 0x0ea9, 0x0eb4, 0x0ebe, 0x0ec6, 0x0eca, + 0x0ecf, 0x0ed9, 0x0edd, 0x0ee4, 0x0eec, 0x0ef3, 0x0ef8, 0x0f04, + 0x0f0a, 0x0f15, 0x0f1b, 0x0f22, 0x0f28, 0x0f33, 0x0f3d, 0x0f45, + 0x0f4c, 0x0f51, 0x0f57, 0x0f5e, 0x0f63, 0x0f69, 0x0f70, 0x0f76, + 0x0f7d, 0x0f82, 0x0f89, 0x0f8d, 0x0f9e, 0x0fa4, 0x0fa9, 0x0fad, + 0x0fb8, 0x0fbe, 0x0fc9, 0x0fd0, 0x0fd6, 0x0fda, 0x0fe1, 0x0fe5, + 0x0fef, 0x0ffa, 0x1000, 0x1004, 0x1009, 0x100f, 0x1013, 0x101a, + 0x101f, 0x1023, 0x1029, 0x102f, 0x1032, 0x1036, 0x1039, 0x103f, + 0x1045, 0x1059, 0x1061, 0x1079, 0x107c, 0x1080, 0x1095, 0x10a1, + 0x10b1, 0x10c3, 0x10cb, 0x10cf, 0x10da, 0x10de, 0x10ea, 0x10f2, + 0x10f4, 0x1100, 0x1105, 0x1111, 0x1141, 0x1149, 0x114d, 0x1153, + 0x1157, 0x115a, 0x116e, 0x1171, 0x1175, 0x117b, 0x117d, 0x1181, + 0x1184, 0x118c, 0x1192, 0x1196, 0x119c, 0x11a2, 0x11a8, 0x11ab, + 0xa76f, 0x11af, 0x11b2, 0x11b6, 0x028d, 0x11be, 0x1210, 0x130e, + 0x140c, 0x1490, 0x1495, 0x1553, 0x156c, 0x1572, 0x1578, 0x157e, + 0x158a, 0x1596, 0x002b, 0x15a1, 0x15b9, 0x15bd, 0x15c1, 0x15c5, + 0x15c9, 0x15cd, 0x15e1, 0x15e5, 0x1649, 0x1662, 0x1688, 0x168e, + 0x174c, 0x1752, 0x1757, 0x1777, 0x1877, 0x187d, 0x1911, 0x19d3, + 0x1a77, 0x1a7f, 0x1a9d, 0x1aa2, 0x1ab6, 0x1ac0, 0x1ac6, 0x1ada, + 0x1adf, 0x1ae5, 0x1af3, 0x1b23, 0x1b30, 0x1b38, 0x1b3c, 0x1b52, + 0x1bc9, 0x1bdb, 0x1bdd, 0x1bdf, 0x3164, 0x1c20, 0x1c22, 0x1c24, + 0x1c26, 0x1c28, 0x1c2a, 0x1c48, 0x1c7e, 0x1cc4, 0x1cd2, 0x1cd7, + 0x1ce0, 0x1ce9, 0x1cfb, 0x1d04, 0x1d09, 0x1d29, 0x1d44, 0x1d46, + 0x1d48, 0x1d4a, 0x1d4c, 0x1d4e, 0x1d50, 0x1d52, 0x1d72, 0x1d74, + 0x1d76, 0x1d78, 0x1d7a, 0x1d81, 0x1d83, 0x1d85, 0x1d87, 0x1d96, + 0x1d98, 0x1d9a, 0x1d9c, 0x1d9e, 0x1da0, 0x1da2, 0x1da4, 0x1da6, + 0x1da8, 0x1daa, 0x1dac, 0x1dae, 0x1db0, 0x1db2, 0x1db6, 0x03f4, + 0x1db8, 0x2207, 0x1dba, 0x2202, 0x1dbc, 0x1dc4, 0x03f4, 0x1dc6, + 0x2207, 0x1dc8, 0x2202, 0x1dca, 0x1dd2, 0x03f4, 0x1dd4, 0x2207, + 0x1dd6, 0x2202, 0x1dd8, 0x1de0, 0x03f4, 0x1de2, 0x2207, 0x1de4, + 0x2202, 0x1de6, 0x1dee, 0x03f4, 0x1df0, 0x2207, 0x1df2, 0x2202, + 0x1df4, 0x1dfe, 0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08, 0x1e0e, + 0x1e2b, 0x062d, 0x1e33, 0x1e3f, 0x062c, 0x1e4f, 0x1ebf, 0x1ecb, + 0x1ede, 0x1ef0, 0x1f03, 0x1f05, 0x1f09, 0x1f0f, 0x1f15, 0x1f17, + 0x1f1b, 0x1f1d, 0x1f25, 0x1f28, 0x1f2a, 0x1f30, 0x1f32, 0x30b5, + 0x1f38, 0x1f90, 0x1fa6, 0x1faa, 0x1fac, 0x1fb1, 0x1ffe, 0x200f, + 0x2110, 0x2120, 0x2126, 0x2220, 0x233e, +}; + +static const uint8_t unicode_decomp_data[9292] = { + 0x20, 0x88, 0x20, 0x84, 0x32, 0x33, 0x20, 0x81, + 0x20, 0xa7, 0x31, 0x6f, 0x31, 0xd0, 0x34, 0x31, + 0xd0, 0x32, 0x33, 0xd0, 0x34, 0x41, 0x80, 0x41, + 0x81, 0x41, 0x82, 0x41, 0x83, 0x41, 0x88, 0x41, + 0x8a, 0x00, 0x00, 0x43, 0xa7, 0x45, 0x80, 0x45, + 0x81, 0x45, 0x82, 0x45, 0x88, 0x49, 0x80, 0x49, + 0x81, 0x49, 0x82, 0x49, 0x88, 0x00, 0x00, 0x4e, + 0x83, 0x4f, 0x80, 0x4f, 0x81, 0x4f, 0x82, 0x4f, + 0x83, 0x4f, 0x88, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x80, 0x55, 0x81, 0x55, 0x82, 0x55, 0x88, 0x59, + 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x80, 0x61, + 0x81, 0x61, 0x82, 0x61, 0x83, 0x61, 0x88, 0x61, + 0x8a, 0x00, 0x00, 0x63, 0xa7, 0x65, 0x80, 0x65, + 0x81, 0x65, 0x82, 0x65, 0x88, 0x69, 0x80, 0x69, + 0x81, 0x69, 0x82, 0x69, 0x88, 0x00, 0x00, 0x6e, + 0x83, 0x6f, 0x80, 0x6f, 0x81, 0x6f, 0x82, 0x6f, + 0x83, 0x6f, 0x88, 0x00, 0x00, 0x00, 0x00, 0x75, + 0x80, 0x75, 0x81, 0x75, 0x82, 0x75, 0x88, 0x79, + 0x81, 0x00, 0x00, 0x79, 0x88, 0x41, 0x84, 0x41, + 0x86, 0x41, 0xa8, 0x43, 0x81, 0x43, 0x82, 0x43, + 0x87, 0x43, 0x8c, 0x44, 0x8c, 0x45, 0x84, 0x45, + 0x86, 0x45, 0x87, 0x45, 0xa8, 0x45, 0x8c, 0x47, + 0x82, 0x47, 0x86, 0x47, 0x87, 0x47, 0xa7, 0x48, + 0x82, 0x49, 0x83, 0x49, 0x84, 0x49, 0x86, 0x49, + 0xa8, 0x49, 0x87, 0x49, 0x4a, 0x69, 0x6a, 0x4a, + 0x82, 0x4b, 0xa7, 0x4c, 0x81, 0x4c, 0xa7, 0x4c, + 0x8c, 0x4c, 0x00, 0x00, 0x6b, 0x20, 0x6b, 0x4e, + 0x81, 0x4e, 0xa7, 0x4e, 0x8c, 0xbc, 0x02, 0x6e, + 0x4f, 0x84, 0x4f, 0x86, 0x4f, 0x8b, 0x52, 0x81, + 0x52, 0xa7, 0x52, 0x8c, 0x53, 0x81, 0x53, 0x82, + 0x53, 0xa7, 0x53, 0x8c, 0x54, 0xa7, 0x54, 0x8c, + 0x55, 0x83, 0x55, 0x84, 0x55, 0x86, 0x55, 0x8a, + 0x55, 0x8b, 0x55, 0xa8, 0x57, 0x82, 0x59, 0x82, + 0x59, 0x88, 0x5a, 0x81, 0x5a, 0x87, 0x5a, 0x8c, + 0x4f, 0x9b, 0x55, 0x9b, 0x44, 0x00, 0x7d, 0x01, + 0x44, 0x00, 0x7e, 0x01, 0x64, 0x00, 0x7e, 0x01, + 0x4c, 0x4a, 0x4c, 0x6a, 0x6c, 0x6a, 0x4e, 0x4a, + 0x4e, 0x6a, 0x6e, 0x6a, 0x41, 0x00, 0x8c, 0x49, + 0x00, 0x8c, 0x4f, 0x00, 0x8c, 0x55, 0x00, 0x8c, + 0xdc, 0x00, 0x84, 0xdc, 0x00, 0x81, 0xdc, 0x00, + 0x8c, 0xdc, 0x00, 0x80, 0xc4, 0x00, 0x84, 0x26, + 0x02, 0x84, 0xc6, 0x00, 0x84, 0x47, 0x8c, 0x4b, + 0x8c, 0x4f, 0xa8, 0xea, 0x01, 0x84, 0xeb, 0x01, + 0x84, 0xb7, 0x01, 0x8c, 0x92, 0x02, 0x8c, 0x6a, + 0x00, 0x8c, 0x44, 0x5a, 0x44, 0x7a, 0x64, 0x7a, + 0x47, 0x81, 0x4e, 0x00, 0x80, 0xc5, 0x00, 0x81, + 0xc6, 0x00, 0x81, 0xd8, 0x00, 0x81, 0x41, 0x8f, + 0x41, 0x91, 0x45, 0x8f, 0x45, 0x91, 0x49, 0x8f, + 0x49, 0x91, 0x4f, 0x8f, 0x4f, 0x91, 0x52, 0x8f, + 0x52, 0x91, 0x55, 0x8f, 0x55, 0x91, 0x53, 0xa6, + 0x54, 0xa6, 0x48, 0x8c, 0x41, 0x00, 0x87, 0x45, + 0x00, 0xa7, 0xd6, 0x00, 0x84, 0xd5, 0x00, 0x84, + 0x4f, 0x00, 0x87, 0x2e, 0x02, 0x84, 0x59, 0x00, + 0x84, 0x68, 0x00, 0x66, 0x02, 0x6a, 0x00, 0x72, + 0x00, 0x79, 0x02, 0x7b, 0x02, 0x81, 0x02, 0x77, + 0x00, 0x79, 0x00, 0x20, 0x86, 0x20, 0x87, 0x20, + 0x8a, 0x20, 0xa8, 0x20, 0x83, 0x20, 0x8b, 0x63, + 0x02, 0x6c, 0x00, 0x73, 0x00, 0x78, 0x00, 0x95, + 0x02, 0x80, 0x81, 0x00, 0x93, 0x88, 0x81, 0x20, + 0xc5, 0x20, 0x81, 0xa8, 0x00, 0x81, 0x91, 0x03, + 0x81, 0x95, 0x03, 0x81, 0x97, 0x03, 0x81, 0x99, + 0x03, 0x81, 0x00, 0x00, 0x00, 0x9f, 0x03, 0x81, + 0x00, 0x00, 0x00, 0xa5, 0x03, 0x81, 0xa9, 0x03, + 0x81, 0xca, 0x03, 0x81, 0x01, 0x03, 0x98, 0x07, + 0xa4, 0x07, 0xb0, 0x00, 0xb4, 0x00, 0xb6, 0x00, + 0xb8, 0x00, 0xca, 0x00, 0x01, 0x03, 0xb8, 0x07, + 0xc4, 0x07, 0xbe, 0x00, 0xc4, 0x00, 0xc8, 0x00, + 0xa5, 0x03, 0x0d, 0x13, 0x00, 0x01, 0x03, 0xd1, + 0x00, 0xd1, 0x07, 0xc6, 0x03, 0xc0, 0x03, 0xba, + 0x03, 0xc1, 0x03, 0xc2, 0x03, 0x00, 0x00, 0x98, + 0x03, 0xb5, 0x03, 0x15, 0x04, 0x80, 0x15, 0x04, + 0x88, 0x00, 0x00, 0x00, 0x13, 0x04, 0x81, 0x06, + 0x04, 0x88, 0x1a, 0x04, 0x81, 0x18, 0x04, 0x80, + 0x23, 0x04, 0x86, 0x18, 0x04, 0x86, 0x38, 0x04, + 0x86, 0x35, 0x04, 0x80, 0x35, 0x04, 0x88, 0x00, + 0x00, 0x00, 0x33, 0x04, 0x81, 0x56, 0x04, 0x88, + 0x3a, 0x04, 0x81, 0x38, 0x04, 0x80, 0x43, 0x04, + 0x86, 0x74, 0x04, 0x8f, 0x16, 0x04, 0x86, 0x10, + 0x04, 0x86, 0x10, 0x04, 0x88, 0x15, 0x04, 0x86, + 0xd8, 0x04, 0x88, 0x16, 0x04, 0x88, 0x17, 0x04, + 0x88, 0x18, 0x04, 0x84, 0x18, 0x04, 0x88, 0x1e, + 0x04, 0x88, 0xe8, 0x04, 0x88, 0x2d, 0x04, 0x88, + 0x23, 0x04, 0x84, 0x23, 0x04, 0x88, 0x23, 0x04, + 0x8b, 0x27, 0x04, 0x88, 0x2b, 0x04, 0x88, 0x65, + 0x05, 0x82, 0x05, 0x27, 0x06, 0x00, 0x2c, 0x00, + 0x2d, 0x21, 0x2d, 0x00, 0x2e, 0x23, 0x2d, 0x27, + 0x06, 0x00, 0x4d, 0x21, 0x4d, 0xa0, 0x4d, 0x23, + 0x4d, 0xd5, 0x06, 0x54, 0x06, 0x00, 0x00, 0x00, + 0x00, 0xc1, 0x06, 0x54, 0x06, 0xd2, 0x06, 0x54, + 0x06, 0x28, 0x09, 0x3c, 0x09, 0x30, 0x09, 0x3c, + 0x09, 0x33, 0x09, 0x3c, 0x09, 0x15, 0x09, 0x00, + 0x27, 0x01, 0x27, 0x02, 0x27, 0x07, 0x27, 0x0c, + 0x27, 0x0d, 0x27, 0x16, 0x27, 0x1a, 0x27, 0xbe, + 0x09, 0x09, 0x00, 0x09, 0x19, 0xa1, 0x09, 0xbc, + 0x09, 0xaf, 0x09, 0xbc, 0x09, 0x32, 0x0a, 0x3c, + 0x0a, 0x38, 0x0a, 0x3c, 0x0a, 0x16, 0x0a, 0x00, + 0x26, 0x01, 0x26, 0x06, 0x26, 0x2b, 0x0a, 0x3c, + 0x0a, 0x47, 0x0b, 0x56, 0x0b, 0x3e, 0x0b, 0x09, + 0x00, 0x09, 0x19, 0x21, 0x0b, 0x3c, 0x0b, 0x92, + 0x0b, 0xd7, 0x0b, 0xbe, 0x0b, 0x08, 0x00, 0x09, + 0x00, 0x08, 0x19, 0x46, 0x0c, 0x56, 0x0c, 0xbf, + 0x0c, 0xd5, 0x0c, 0xc6, 0x0c, 0xd5, 0x0c, 0xc2, + 0x0c, 0x04, 0x00, 0x08, 0x13, 0x3e, 0x0d, 0x08, + 0x00, 0x09, 0x00, 0x08, 0x19, 0xd9, 0x0d, 0xca, + 0x0d, 0xca, 0x0d, 0x0f, 0x05, 0x12, 0x00, 0x0f, + 0x15, 0x4d, 0x0e, 0x32, 0x0e, 0xcd, 0x0e, 0xb2, + 0x0e, 0x99, 0x0e, 0x12, 0x00, 0x12, 0x08, 0x42, + 0x0f, 0xb7, 0x0f, 0x4c, 0x0f, 0xb7, 0x0f, 0x51, + 0x0f, 0xb7, 0x0f, 0x56, 0x0f, 0xb7, 0x0f, 0x5b, + 0x0f, 0xb7, 0x0f, 0x40, 0x0f, 0xb5, 0x0f, 0x71, + 0x0f, 0x72, 0x0f, 0x71, 0x0f, 0x00, 0x03, 0x41, + 0x0f, 0xb2, 0x0f, 0x81, 0x0f, 0xb3, 0x0f, 0x80, + 0x0f, 0xb3, 0x0f, 0x81, 0x0f, 0x71, 0x0f, 0x80, + 0x0f, 0x92, 0x0f, 0xb7, 0x0f, 0x9c, 0x0f, 0xb7, + 0x0f, 0xa1, 0x0f, 0xb7, 0x0f, 0xa6, 0x0f, 0xb7, + 0x0f, 0xab, 0x0f, 0xb7, 0x0f, 0x90, 0x0f, 0xb5, + 0x0f, 0x25, 0x10, 0x2e, 0x10, 0x05, 0x1b, 0x35, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1b, 0x35, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x09, 0x1b, 0x35, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0x35, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x1b, 0x35, + 0x1b, 0x11, 0x1b, 0x35, 0x1b, 0x3a, 0x1b, 0x35, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x1b, 0x35, + 0x1b, 0x3e, 0x1b, 0x35, 0x1b, 0x42, 0x1b, 0x35, + 0x1b, 0x41, 0x00, 0xc6, 0x00, 0x42, 0x00, 0x00, + 0x00, 0x44, 0x00, 0x45, 0x00, 0x8e, 0x01, 0x47, + 0x00, 0x4f, 0x00, 0x22, 0x02, 0x50, 0x00, 0x52, + 0x00, 0x54, 0x00, 0x55, 0x00, 0x57, 0x00, 0x61, + 0x00, 0x50, 0x02, 0x51, 0x02, 0x02, 0x1d, 0x62, + 0x00, 0x64, 0x00, 0x65, 0x00, 0x59, 0x02, 0x5b, + 0x02, 0x5c, 0x02, 0x67, 0x00, 0x00, 0x00, 0x6b, + 0x00, 0x6d, 0x00, 0x4b, 0x01, 0x6f, 0x00, 0x54, + 0x02, 0x16, 0x1d, 0x17, 0x1d, 0x70, 0x00, 0x74, + 0x00, 0x75, 0x00, 0x1d, 0x1d, 0x6f, 0x02, 0x76, + 0x00, 0x25, 0x1d, 0xb2, 0x03, 0xb3, 0x03, 0xb4, + 0x03, 0xc6, 0x03, 0xc7, 0x03, 0x69, 0x00, 0x72, + 0x00, 0x75, 0x00, 0x76, 0x00, 0xb2, 0x03, 0xb3, + 0x03, 0xc1, 0x03, 0xc6, 0x03, 0xc7, 0x03, 0x52, + 0x02, 0x63, 0x00, 0x55, 0x02, 0xf0, 0x00, 0x5c, + 0x02, 0x66, 0x00, 0x5f, 0x02, 0x61, 0x02, 0x65, + 0x02, 0x68, 0x02, 0x69, 0x02, 0x6a, 0x02, 0x7b, + 0x1d, 0x9d, 0x02, 0x6d, 0x02, 0x85, 0x1d, 0x9f, + 0x02, 0x71, 0x02, 0x70, 0x02, 0x72, 0x02, 0x73, + 0x02, 0x74, 0x02, 0x75, 0x02, 0x78, 0x02, 0x82, + 0x02, 0x83, 0x02, 0xab, 0x01, 0x89, 0x02, 0x8a, + 0x02, 0x1c, 0x1d, 0x8b, 0x02, 0x8c, 0x02, 0x7a, + 0x00, 0x90, 0x02, 0x91, 0x02, 0x92, 0x02, 0xb8, + 0x03, 0x41, 0x00, 0xa5, 0x42, 0x00, 0x87, 0x42, + 0x00, 0xa3, 0x42, 0x00, 0xb1, 0xc7, 0x00, 0x81, + 0x44, 0x00, 0x87, 0x44, 0x00, 0xa3, 0x44, 0x00, + 0xb1, 0x44, 0x00, 0xa7, 0x44, 0x00, 0xad, 0x12, + 0x01, 0x80, 0x12, 0x01, 0x81, 0x45, 0x00, 0xad, + 0x45, 0x00, 0xb0, 0x28, 0x02, 0x86, 0x46, 0x00, + 0x87, 0x47, 0x00, 0x84, 0x48, 0x00, 0x87, 0x48, + 0x00, 0xa3, 0x48, 0x00, 0x88, 0x48, 0x00, 0xa7, + 0x48, 0x00, 0xae, 0x49, 0x00, 0xb0, 0xcf, 0x00, + 0x81, 0x4b, 0x00, 0x81, 0x4b, 0x00, 0xa3, 0x4b, + 0x00, 0xb1, 0x4c, 0x00, 0xa3, 0x36, 0x1e, 0x84, + 0x4c, 0xb1, 0x4c, 0xad, 0x4d, 0x81, 0x4d, 0x87, + 0x4d, 0xa3, 0x4e, 0x87, 0x4e, 0xa3, 0x4e, 0xb1, + 0x4e, 0xad, 0xd5, 0x00, 0x81, 0xd5, 0x00, 0x88, + 0x4c, 0x01, 0x80, 0x4c, 0x01, 0x81, 0x50, 0x00, + 0x81, 0x50, 0x00, 0x87, 0x52, 0x00, 0x87, 0x52, + 0x00, 0xa3, 0x5a, 0x1e, 0x84, 0x52, 0x00, 0xb1, + 0x53, 0x00, 0x87, 0x53, 0x00, 0xa3, 0x5a, 0x01, + 0x87, 0x60, 0x01, 0x87, 0x62, 0x1e, 0x87, 0x54, + 0x00, 0x87, 0x54, 0x00, 0xa3, 0x54, 0x00, 0xb1, + 0x54, 0x00, 0xad, 0x55, 0x00, 0xa4, 0x55, 0x00, + 0xb0, 0x55, 0x00, 0xad, 0x68, 0x01, 0x81, 0x6a, + 0x01, 0x88, 0x56, 0x83, 0x56, 0xa3, 0x57, 0x80, + 0x57, 0x81, 0x57, 0x88, 0x57, 0x87, 0x57, 0xa3, + 0x58, 0x87, 0x58, 0x88, 0x59, 0x87, 0x5a, 0x82, + 0x5a, 0xa3, 0x5a, 0xb1, 0x68, 0xb1, 0x74, 0x88, + 0x77, 0x8a, 0x79, 0x8a, 0x61, 0x00, 0xbe, 0x02, + 0x7f, 0x01, 0x87, 0x41, 0x00, 0xa3, 0x41, 0x00, + 0x89, 0xc2, 0x00, 0x81, 0xc2, 0x00, 0x80, 0xc2, + 0x00, 0x89, 0xc2, 0x00, 0x83, 0xa0, 0x1e, 0x82, + 0x02, 0x01, 0x81, 0x02, 0x01, 0x80, 0x02, 0x01, + 0x89, 0x02, 0x01, 0x83, 0xa0, 0x1e, 0x86, 0x45, + 0x00, 0xa3, 0x45, 0x00, 0x89, 0x45, 0x00, 0x83, + 0xca, 0x00, 0x81, 0xca, 0x00, 0x80, 0xca, 0x00, + 0x89, 0xca, 0x00, 0x83, 0xb8, 0x1e, 0x82, 0x49, + 0x00, 0x89, 0x49, 0x00, 0xa3, 0x4f, 0x00, 0xa3, + 0x4f, 0x00, 0x89, 0xd4, 0x00, 0x81, 0xd4, 0x00, + 0x80, 0xd4, 0x00, 0x89, 0xd4, 0x00, 0x83, 0xcc, + 0x1e, 0x82, 0xa0, 0x01, 0x81, 0xa0, 0x01, 0x80, + 0xa0, 0x01, 0x89, 0xa0, 0x01, 0x83, 0xa0, 0x01, + 0xa3, 0x55, 0x00, 0xa3, 0x55, 0x00, 0x89, 0xaf, + 0x01, 0x81, 0xaf, 0x01, 0x80, 0xaf, 0x01, 0x89, + 0xaf, 0x01, 0x83, 0xaf, 0x01, 0xa3, 0x59, 0x00, + 0x80, 0x59, 0x00, 0xa3, 0x59, 0x00, 0x89, 0x59, + 0x00, 0x83, 0xb1, 0x03, 0x13, 0x03, 0x00, 0x1f, + 0x80, 0x00, 0x1f, 0x81, 0x00, 0x1f, 0xc2, 0x91, + 0x03, 0x13, 0x03, 0x08, 0x1f, 0x80, 0x08, 0x1f, + 0x81, 0x08, 0x1f, 0xc2, 0xb5, 0x03, 0x13, 0x03, + 0x10, 0x1f, 0x80, 0x10, 0x1f, 0x81, 0x95, 0x03, + 0x13, 0x03, 0x18, 0x1f, 0x80, 0x18, 0x1f, 0x81, + 0xb7, 0x03, 0x93, 0xb7, 0x03, 0x94, 0x20, 0x1f, + 0x80, 0x21, 0x1f, 0x80, 0x20, 0x1f, 0x81, 0x21, + 0x1f, 0x81, 0x20, 0x1f, 0xc2, 0x21, 0x1f, 0xc2, + 0x97, 0x03, 0x93, 0x97, 0x03, 0x94, 0x28, 0x1f, + 0x80, 0x29, 0x1f, 0x80, 0x28, 0x1f, 0x81, 0x29, + 0x1f, 0x81, 0x28, 0x1f, 0xc2, 0x29, 0x1f, 0xc2, + 0xb9, 0x03, 0x93, 0xb9, 0x03, 0x94, 0x30, 0x1f, + 0x80, 0x31, 0x1f, 0x80, 0x30, 0x1f, 0x81, 0x31, + 0x1f, 0x81, 0x30, 0x1f, 0xc2, 0x31, 0x1f, 0xc2, + 0x99, 0x03, 0x93, 0x99, 0x03, 0x94, 0x38, 0x1f, + 0x80, 0x39, 0x1f, 0x80, 0x38, 0x1f, 0x81, 0x39, + 0x1f, 0x81, 0x38, 0x1f, 0xc2, 0x39, 0x1f, 0xc2, + 0xbf, 0x03, 0x93, 0xbf, 0x03, 0x94, 0x40, 0x1f, + 0x80, 0x40, 0x1f, 0x81, 0x9f, 0x03, 0x13, 0x03, + 0x48, 0x1f, 0x80, 0x48, 0x1f, 0x81, 0xc5, 0x03, + 0x13, 0x03, 0x50, 0x1f, 0x80, 0x50, 0x1f, 0x81, + 0x50, 0x1f, 0xc2, 0xa5, 0x03, 0x94, 0x00, 0x00, + 0x00, 0x59, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x59, + 0x1f, 0x81, 0x00, 0x00, 0x00, 0x59, 0x1f, 0xc2, + 0xc9, 0x03, 0x93, 0xc9, 0x03, 0x94, 0x60, 0x1f, + 0x80, 0x61, 0x1f, 0x80, 0x60, 0x1f, 0x81, 0x61, + 0x1f, 0x81, 0x60, 0x1f, 0xc2, 0x61, 0x1f, 0xc2, + 0xa9, 0x03, 0x93, 0xa9, 0x03, 0x94, 0x68, 0x1f, + 0x80, 0x69, 0x1f, 0x80, 0x68, 0x1f, 0x81, 0x69, + 0x1f, 0x81, 0x68, 0x1f, 0xc2, 0x69, 0x1f, 0xc2, + 0xb1, 0x03, 0x80, 0xb5, 0x03, 0x80, 0xb7, 0x03, + 0x80, 0xb9, 0x03, 0x80, 0xbf, 0x03, 0x80, 0xc5, + 0x03, 0x80, 0xc9, 0x03, 0x80, 0x00, 0x1f, 0x45, + 0x03, 0x20, 0x1f, 0x45, 0x03, 0x60, 0x1f, 0x45, + 0x03, 0xb1, 0x03, 0x86, 0xb1, 0x03, 0x84, 0x70, + 0x1f, 0xc5, 0xb1, 0x03, 0xc5, 0xac, 0x03, 0xc5, + 0x00, 0x00, 0x00, 0xb1, 0x03, 0xc2, 0xb6, 0x1f, + 0xc5, 0x91, 0x03, 0x86, 0x91, 0x03, 0x84, 0x91, + 0x03, 0x80, 0x91, 0x03, 0xc5, 0x20, 0x93, 0x20, + 0x93, 0x20, 0xc2, 0xa8, 0x00, 0xc2, 0x74, 0x1f, + 0xc5, 0xb7, 0x03, 0xc5, 0xae, 0x03, 0xc5, 0x00, + 0x00, 0x00, 0xb7, 0x03, 0xc2, 0xc6, 0x1f, 0xc5, + 0x95, 0x03, 0x80, 0x97, 0x03, 0x80, 0x97, 0x03, + 0xc5, 0xbf, 0x1f, 0x80, 0xbf, 0x1f, 0x81, 0xbf, + 0x1f, 0xc2, 0xb9, 0x03, 0x86, 0xb9, 0x03, 0x84, + 0xca, 0x03, 0x80, 0x00, 0x03, 0xb9, 0x42, 0xca, + 0x42, 0x99, 0x06, 0x99, 0x04, 0x99, 0x00, 0xfe, + 0x1f, 0x80, 0xfe, 0x1f, 0x81, 0xfe, 0x1f, 0xc2, + 0xc5, 0x03, 0x86, 0xc5, 0x03, 0x84, 0xcb, 0x03, + 0x80, 0x00, 0x03, 0xc1, 0x13, 0xc1, 0x14, 0xc5, + 0x42, 0xcb, 0x42, 0xa5, 0x06, 0xa5, 0x04, 0xa5, + 0x00, 0xa1, 0x03, 0x94, 0xa8, 0x00, 0x80, 0x85, + 0x03, 0x60, 0x00, 0x7c, 0x1f, 0xc5, 0xc9, 0x03, + 0xc5, 0xce, 0x03, 0xc5, 0x00, 0x00, 0x00, 0xc9, + 0x03, 0xc2, 0xf6, 0x1f, 0xc5, 0x9f, 0x03, 0x80, + 0xa9, 0x03, 0x80, 0xa9, 0x03, 0xc5, 0x20, 0x94, + 0x02, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0xb3, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x32, 0x20, 0x32, 0x20, 0x32, 0x20, + 0x00, 0x00, 0x00, 0x35, 0x20, 0x35, 0x20, 0x35, + 0x20, 0x00, 0x00, 0x00, 0x21, 0x21, 0x00, 0x00, + 0x20, 0x85, 0x3f, 0x3f, 0x3f, 0x21, 0x21, 0x3f, + 0x32, 0x20, 0x00, 0x00, 0x00, 0x00, 0x30, 0x69, + 0x00, 0x00, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x2b, 0x3d, 0x28, 0x29, 0x6e, 0x30, 0x00, 0x2b, + 0x00, 0x12, 0x22, 0x3d, 0x00, 0x28, 0x00, 0x29, + 0x00, 0x00, 0x00, 0x61, 0x00, 0x65, 0x00, 0x6f, + 0x00, 0x78, 0x00, 0x59, 0x02, 0x68, 0x6b, 0x6c, + 0x6d, 0x6e, 0x70, 0x73, 0x74, 0x52, 0x73, 0x61, + 0x2f, 0x63, 0x61, 0x2f, 0x73, 0xb0, 0x00, 0x43, + 0x63, 0x2f, 0x6f, 0x63, 0x2f, 0x75, 0xb0, 0x00, + 0x46, 0x48, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, + 0xdf, 0x01, 0x01, 0x04, 0x24, 0x4e, 0x6f, 0x50, + 0x51, 0x52, 0x52, 0x52, 0x53, 0x4d, 0x54, 0x45, + 0x4c, 0x54, 0x4d, 0x4b, 0x00, 0xc5, 0x00, 0x42, + 0x43, 0x00, 0x65, 0x45, 0x46, 0x00, 0x4d, 0x6f, + 0xd0, 0x05, 0x46, 0x41, 0x58, 0xc0, 0x03, 0xb3, + 0x03, 0x93, 0x03, 0xa0, 0x03, 0x11, 0x22, 0x44, + 0x64, 0x65, 0x69, 0x6a, 0x31, 0xd0, 0x37, 0x31, + 0xd0, 0x39, 0x31, 0xd0, 0x31, 0x30, 0x31, 0xd0, + 0x33, 0x32, 0xd0, 0x33, 0x31, 0xd0, 0x35, 0x32, + 0xd0, 0x35, 0x33, 0xd0, 0x35, 0x34, 0xd0, 0x35, + 0x31, 0xd0, 0x36, 0x35, 0xd0, 0x36, 0x31, 0xd0, + 0x38, 0x33, 0xd0, 0x38, 0x35, 0xd0, 0x38, 0x37, + 0xd0, 0x38, 0x31, 0xd0, 0x49, 0x49, 0x49, 0x49, + 0x49, 0x49, 0x56, 0x56, 0x49, 0x56, 0x49, 0x49, + 0x56, 0x49, 0x49, 0x49, 0x49, 0x58, 0x58, 0x49, + 0x58, 0x49, 0x49, 0x4c, 0x43, 0x44, 0x4d, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x76, 0x76, + 0x69, 0x76, 0x69, 0x69, 0x76, 0x69, 0x69, 0x69, + 0x69, 0x78, 0x78, 0x69, 0x78, 0x69, 0x69, 0x6c, + 0x63, 0x64, 0x6d, 0x30, 0xd0, 0x33, 0x90, 0x21, + 0xb8, 0x92, 0x21, 0xb8, 0x94, 0x21, 0xb8, 0xd0, + 0x21, 0xb8, 0xd4, 0x21, 0xb8, 0xd2, 0x21, 0xb8, + 0x03, 0x22, 0xb8, 0x08, 0x22, 0xb8, 0x0b, 0x22, + 0xb8, 0x23, 0x22, 0xb8, 0x00, 0x00, 0x00, 0x25, + 0x22, 0xb8, 0x2b, 0x22, 0x2b, 0x22, 0x2b, 0x22, + 0x00, 0x00, 0x00, 0x2e, 0x22, 0x2e, 0x22, 0x2e, + 0x22, 0x00, 0x00, 0x00, 0x3c, 0x22, 0xb8, 0x43, + 0x22, 0xb8, 0x45, 0x22, 0xb8, 0x00, 0x00, 0x00, + 0x48, 0x22, 0xb8, 0x3d, 0x00, 0xb8, 0x00, 0x00, + 0x00, 0x61, 0x22, 0xb8, 0x4d, 0x22, 0xb8, 0x3c, + 0x00, 0xb8, 0x3e, 0x00, 0xb8, 0x64, 0x22, 0xb8, + 0x65, 0x22, 0xb8, 0x72, 0x22, 0xb8, 0x76, 0x22, + 0xb8, 0x7a, 0x22, 0xb8, 0x82, 0x22, 0xb8, 0x86, + 0x22, 0xb8, 0xa2, 0x22, 0xb8, 0xa8, 0x22, 0xb8, + 0xa9, 0x22, 0xb8, 0xab, 0x22, 0xb8, 0x7c, 0x22, + 0xb8, 0x91, 0x22, 0xb8, 0xb2, 0x22, 0x38, 0x03, + 0x08, 0x30, 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, + 0x32, 0x30, 0x28, 0x00, 0x31, 0x00, 0x29, 0x00, + 0x28, 0x00, 0x31, 0x00, 0x30, 0x00, 0x29, 0x00, + 0x28, 0x32, 0x30, 0x29, 0x31, 0x00, 0x2e, 0x00, + 0x31, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x32, 0x30, + 0x2e, 0x28, 0x00, 0x61, 0x00, 0x29, 0x00, 0x41, + 0x00, 0x61, 0x00, 0x2b, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x3a, 0x3a, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, + 0x3d, 0xdd, 0x2a, 0xb8, 0x6a, 0x56, 0x00, 0x4e, + 0x00, 0x28, 0x36, 0x3f, 0x59, 0x85, 0x8c, 0xa0, + 0xba, 0x3f, 0x51, 0x00, 0x26, 0x2c, 0x43, 0x57, + 0x6c, 0xa1, 0xb6, 0xc1, 0x9b, 0x52, 0x00, 0x5e, + 0x7a, 0x7f, 0x9d, 0xa6, 0xc1, 0xce, 0xe7, 0xb6, + 0x53, 0xc8, 0x53, 0xe3, 0x53, 0xd7, 0x56, 0x1f, + 0x57, 0xeb, 0x58, 0x02, 0x59, 0x0a, 0x59, 0x15, + 0x59, 0x27, 0x59, 0x73, 0x59, 0x50, 0x5b, 0x80, + 0x5b, 0xf8, 0x5b, 0x0f, 0x5c, 0x22, 0x5c, 0x38, + 0x5c, 0x6e, 0x5c, 0x71, 0x5c, 0xdb, 0x5d, 0xe5, + 0x5d, 0xf1, 0x5d, 0xfe, 0x5d, 0x72, 0x5e, 0x7a, + 0x5e, 0x7f, 0x5e, 0xf4, 0x5e, 0xfe, 0x5e, 0x0b, + 0x5f, 0x13, 0x5f, 0x50, 0x5f, 0x61, 0x5f, 0x73, + 0x5f, 0xc3, 0x5f, 0x08, 0x62, 0x36, 0x62, 0x4b, + 0x62, 0x2f, 0x65, 0x34, 0x65, 0x87, 0x65, 0x97, + 0x65, 0xa4, 0x65, 0xb9, 0x65, 0xe0, 0x65, 0xe5, + 0x65, 0xf0, 0x66, 0x08, 0x67, 0x28, 0x67, 0x20, + 0x6b, 0x62, 0x6b, 0x79, 0x6b, 0xb3, 0x6b, 0xcb, + 0x6b, 0xd4, 0x6b, 0xdb, 0x6b, 0x0f, 0x6c, 0x14, + 0x6c, 0x34, 0x6c, 0x6b, 0x70, 0x2a, 0x72, 0x36, + 0x72, 0x3b, 0x72, 0x3f, 0x72, 0x47, 0x72, 0x59, + 0x72, 0x5b, 0x72, 0xac, 0x72, 0x84, 0x73, 0x89, + 0x73, 0xdc, 0x74, 0xe6, 0x74, 0x18, 0x75, 0x1f, + 0x75, 0x28, 0x75, 0x30, 0x75, 0x8b, 0x75, 0x92, + 0x75, 0x76, 0x76, 0x7d, 0x76, 0xae, 0x76, 0xbf, + 0x76, 0xee, 0x76, 0xdb, 0x77, 0xe2, 0x77, 0xf3, + 0x77, 0x3a, 0x79, 0xb8, 0x79, 0xbe, 0x79, 0x74, + 0x7a, 0xcb, 0x7a, 0xf9, 0x7a, 0x73, 0x7c, 0xf8, + 0x7c, 0x36, 0x7f, 0x51, 0x7f, 0x8a, 0x7f, 0xbd, + 0x7f, 0x01, 0x80, 0x0c, 0x80, 0x12, 0x80, 0x33, + 0x80, 0x7f, 0x80, 0x89, 0x80, 0xe3, 0x81, 0x00, + 0x07, 0x10, 0x19, 0x29, 0x38, 0x3c, 0x8b, 0x8f, + 0x95, 0x4d, 0x86, 0x6b, 0x86, 0x40, 0x88, 0x4c, + 0x88, 0x63, 0x88, 0x7e, 0x89, 0x8b, 0x89, 0xd2, + 0x89, 0x00, 0x8a, 0x37, 0x8c, 0x46, 0x8c, 0x55, + 0x8c, 0x78, 0x8c, 0x9d, 0x8c, 0x64, 0x8d, 0x70, + 0x8d, 0xb3, 0x8d, 0xab, 0x8e, 0xca, 0x8e, 0x9b, + 0x8f, 0xb0, 0x8f, 0xb5, 0x8f, 0x91, 0x90, 0x49, + 0x91, 0xc6, 0x91, 0xcc, 0x91, 0xd1, 0x91, 0x77, + 0x95, 0x80, 0x95, 0x1c, 0x96, 0xb6, 0x96, 0xb9, + 0x96, 0xe8, 0x96, 0x51, 0x97, 0x5e, 0x97, 0x62, + 0x97, 0x69, 0x97, 0xcb, 0x97, 0xed, 0x97, 0xf3, + 0x97, 0x01, 0x98, 0xa8, 0x98, 0xdb, 0x98, 0xdf, + 0x98, 0x96, 0x99, 0x99, 0x99, 0xac, 0x99, 0xa8, + 0x9a, 0xd8, 0x9a, 0xdf, 0x9a, 0x25, 0x9b, 0x2f, + 0x9b, 0x32, 0x9b, 0x3c, 0x9b, 0x5a, 0x9b, 0xe5, + 0x9c, 0x75, 0x9e, 0x7f, 0x9e, 0xa5, 0x9e, 0x00, + 0x16, 0x1e, 0x28, 0x2c, 0x54, 0x58, 0x69, 0x6e, + 0x7b, 0x96, 0xa5, 0xad, 0xe8, 0xf7, 0xfb, 0x12, + 0x30, 0x00, 0x00, 0x41, 0x53, 0x44, 0x53, 0x45, + 0x53, 0x4b, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x4d, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x4f, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x51, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x53, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x57, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x59, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x5d, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x5f, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x61, 0x30, 0x99, 0x30, 0x64, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x66, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x68, 0x30, 0x99, + 0x30, 0x6f, 0x30, 0x99, 0x30, 0x72, 0x30, 0x99, + 0x30, 0x75, 0x30, 0x99, 0x30, 0x78, 0x30, 0x99, + 0x30, 0x7b, 0x30, 0x99, 0x30, 0x46, 0x30, 0x99, + 0x30, 0x20, 0x00, 0x99, 0x30, 0x9d, 0x30, 0x99, + 0x30, 0x88, 0x30, 0x8a, 0x30, 0xab, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xad, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x30, 0x99, + 0x30, 0xc4, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x30, 0x99, 0x30, 0xcf, 0x30, 0x99, + 0x30, 0xd2, 0x30, 0x99, 0x30, 0xd5, 0x30, 0x99, + 0x30, 0xd8, 0x30, 0x99, 0x30, 0xdb, 0x30, 0x99, + 0x30, 0xa6, 0x30, 0x99, 0x30, 0xef, 0x30, 0x99, + 0x30, 0xfd, 0x30, 0x99, 0x30, 0xb3, 0x30, 0xc8, + 0x30, 0x00, 0x11, 0x00, 0x01, 0xaa, 0x02, 0xac, + 0xad, 0x03, 0x04, 0x05, 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0x1a, 0x06, 0x07, 0x08, 0x21, 0x09, + 0x11, 0x61, 0x11, 0x14, 0x11, 0x4c, 0x00, 0x01, + 0xb3, 0xb4, 0xb8, 0xba, 0xbf, 0xc3, 0xc5, 0x08, + 0xc9, 0xcb, 0x09, 0x0a, 0x0c, 0x0e, 0x0f, 0x13, + 0x15, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x22, + 0x2c, 0x33, 0x38, 0xdd, 0xde, 0x43, 0x44, 0x45, + 0x70, 0x71, 0x74, 0x7d, 0x7e, 0x80, 0x8a, 0x8d, + 0x00, 0x4e, 0x8c, 0x4e, 0x09, 0x4e, 0xdb, 0x56, + 0x0a, 0x4e, 0x2d, 0x4e, 0x0b, 0x4e, 0x32, 0x75, + 0x59, 0x4e, 0x19, 0x4e, 0x01, 0x4e, 0x29, 0x59, + 0x30, 0x57, 0xba, 0x4e, 0x28, 0x00, 0x29, 0x00, + 0x00, 0x11, 0x02, 0x11, 0x03, 0x11, 0x05, 0x11, + 0x06, 0x11, 0x07, 0x11, 0x09, 0x11, 0x0b, 0x11, + 0x0c, 0x11, 0x0e, 0x11, 0x0f, 0x11, 0x10, 0x11, + 0x11, 0x11, 0x12, 0x11, 0x28, 0x00, 0x00, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x02, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x05, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x09, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0b, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0e, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0c, 0x11, + 0x6e, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0b, 0x11, + 0x69, 0x11, 0x0c, 0x11, 0x65, 0x11, 0xab, 0x11, + 0x29, 0x00, 0x28, 0x00, 0x0b, 0x11, 0x69, 0x11, + 0x12, 0x11, 0x6e, 0x11, 0x29, 0x00, 0x28, 0x00, + 0x29, 0x00, 0x00, 0x4e, 0x8c, 0x4e, 0x09, 0x4e, + 0xdb, 0x56, 0x94, 0x4e, 0x6d, 0x51, 0x03, 0x4e, + 0x6b, 0x51, 0x5d, 0x4e, 0x41, 0x53, 0x08, 0x67, + 0x6b, 0x70, 0x34, 0x6c, 0x28, 0x67, 0xd1, 0x91, + 0x1f, 0x57, 0xe5, 0x65, 0x2a, 0x68, 0x09, 0x67, + 0x3e, 0x79, 0x0d, 0x54, 0x79, 0x72, 0xa1, 0x8c, + 0x5d, 0x79, 0xb4, 0x52, 0xe3, 0x4e, 0x7c, 0x54, + 0x66, 0x5b, 0xe3, 0x76, 0x01, 0x4f, 0xc7, 0x8c, + 0x54, 0x53, 0x6d, 0x79, 0x11, 0x4f, 0xea, 0x81, + 0xf3, 0x81, 0x4f, 0x55, 0x7c, 0x5e, 0x87, 0x65, + 0x8f, 0x7b, 0x50, 0x54, 0x45, 0x32, 0x00, 0x31, + 0x00, 0x33, 0x00, 0x30, 0x00, 0x00, 0x11, 0x00, + 0x02, 0x03, 0x05, 0x06, 0x07, 0x09, 0x0b, 0x0c, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x00, 0x11, 0x00, + 0x61, 0x02, 0x61, 0x03, 0x61, 0x05, 0x61, 0x06, + 0x61, 0x07, 0x61, 0x09, 0x61, 0x0b, 0x61, 0x0c, + 0x61, 0x0e, 0x11, 0x61, 0x11, 0x00, 0x11, 0x0e, + 0x61, 0xb7, 0x00, 0x69, 0x0b, 0x11, 0x01, 0x63, + 0x00, 0x69, 0x0b, 0x11, 0x6e, 0x11, 0x00, 0x4e, + 0x8c, 0x4e, 0x09, 0x4e, 0xdb, 0x56, 0x94, 0x4e, + 0x6d, 0x51, 0x03, 0x4e, 0x6b, 0x51, 0x5d, 0x4e, + 0x41, 0x53, 0x08, 0x67, 0x6b, 0x70, 0x34, 0x6c, + 0x28, 0x67, 0xd1, 0x91, 0x1f, 0x57, 0xe5, 0x65, + 0x2a, 0x68, 0x09, 0x67, 0x3e, 0x79, 0x0d, 0x54, + 0x79, 0x72, 0xa1, 0x8c, 0x5d, 0x79, 0xb4, 0x52, + 0xd8, 0x79, 0x37, 0x75, 0x73, 0x59, 0x69, 0x90, + 0x2a, 0x51, 0x70, 0x53, 0xe8, 0x6c, 0x05, 0x98, + 0x11, 0x4f, 0x99, 0x51, 0x63, 0x6b, 0x0a, 0x4e, + 0x2d, 0x4e, 0x0b, 0x4e, 0xe6, 0x5d, 0xf3, 0x53, + 0x3b, 0x53, 0x97, 0x5b, 0x66, 0x5b, 0xe3, 0x76, + 0x01, 0x4f, 0xc7, 0x8c, 0x54, 0x53, 0x1c, 0x59, + 0x33, 0x00, 0x36, 0x00, 0x34, 0x00, 0x30, 0x00, + 0x35, 0x30, 0x31, 0x00, 0x08, 0x67, 0x31, 0x00, + 0x30, 0x00, 0x08, 0x67, 0x48, 0x67, 0x65, 0x72, + 0x67, 0x65, 0x56, 0x4c, 0x54, 0x44, 0xa2, 0x30, + 0x00, 0x02, 0x04, 0x06, 0x08, 0x09, 0x0b, 0x0d, + 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, + 0x1f, 0x22, 0x24, 0x26, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x30, 0x33, 0x36, 0x39, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x42, 0x44, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0xe4, + 0x4e, 0x8c, 0x54, 0xa1, 0x30, 0x01, 0x30, 0x5b, + 0x27, 0x01, 0x4a, 0x34, 0x00, 0x01, 0x52, 0x39, + 0x01, 0xa2, 0x30, 0x00, 0x5a, 0x49, 0xa4, 0x30, + 0x00, 0x27, 0x4f, 0x0c, 0xa4, 0x30, 0x00, 0x4f, + 0x1d, 0x02, 0x05, 0x4f, 0xa8, 0x30, 0x00, 0x11, + 0x07, 0x54, 0x21, 0xa8, 0x30, 0x00, 0x54, 0x03, + 0x54, 0xa4, 0x30, 0x06, 0x4f, 0x15, 0x06, 0x58, + 0x3c, 0x07, 0x00, 0x46, 0xab, 0x30, 0x00, 0x3e, + 0x18, 0x1d, 0x00, 0x42, 0x3f, 0x51, 0xac, 0x30, + 0x00, 0x41, 0x47, 0x00, 0x47, 0x32, 0xae, 0x30, + 0xac, 0x30, 0xae, 0x30, 0x00, 0x1d, 0x4e, 0xad, + 0x30, 0x00, 0x38, 0x3d, 0x4f, 0x01, 0x3e, 0x13, + 0x4f, 0xad, 0x30, 0xed, 0x30, 0xad, 0x30, 0x00, + 0x40, 0x03, 0x3c, 0x33, 0xad, 0x30, 0x00, 0x40, + 0x34, 0x4f, 0x1b, 0x3e, 0xad, 0x30, 0x00, 0x40, + 0x42, 0x16, 0x1b, 0xb0, 0x30, 0x00, 0x39, 0x30, + 0xa4, 0x30, 0x0c, 0x45, 0x3c, 0x24, 0x4f, 0x0b, + 0x47, 0x18, 0x00, 0x49, 0xaf, 0x30, 0x00, 0x3e, + 0x4d, 0x1e, 0xb1, 0x30, 0x00, 0x4b, 0x08, 0x02, + 0x3a, 0x19, 0x02, 0x4b, 0x2c, 0xa4, 0x30, 0x11, + 0x00, 0x0b, 0x47, 0xb5, 0x30, 0x00, 0x3e, 0x0c, + 0x47, 0x2b, 0xb0, 0x30, 0x07, 0x3a, 0x43, 0x00, + 0xb9, 0x30, 0x02, 0x3a, 0x08, 0x02, 0x3a, 0x0f, + 0x07, 0x43, 0x00, 0xb7, 0x30, 0x10, 0x00, 0x12, + 0x34, 0x11, 0x3c, 0x13, 0x17, 0xa4, 0x30, 0x2a, + 0x1f, 0x24, 0x2b, 0x00, 0x20, 0xbb, 0x30, 0x16, + 0x41, 0x00, 0x38, 0x0d, 0xc4, 0x30, 0x0d, 0x38, + 0x00, 0xd0, 0x30, 0x00, 0x2c, 0x1c, 0x1b, 0xa2, + 0x30, 0x32, 0x00, 0x17, 0x26, 0x49, 0xaf, 0x30, + 0x25, 0x00, 0x3c, 0xb3, 0x30, 0x21, 0x00, 0x20, + 0x38, 0xa1, 0x30, 0x34, 0x00, 0x48, 0x22, 0x28, + 0xa3, 0x30, 0x32, 0x00, 0x59, 0x25, 0xa7, 0x30, + 0x2f, 0x1c, 0x10, 0x00, 0x44, 0xd5, 0x30, 0x00, + 0x14, 0x1e, 0xaf, 0x30, 0x29, 0x00, 0x10, 0x4d, + 0x3c, 0xda, 0x30, 0xbd, 0x30, 0xb8, 0x30, 0x22, + 0x13, 0x1a, 0x20, 0x33, 0x0c, 0x22, 0x3b, 0x01, + 0x22, 0x44, 0x00, 0x21, 0x44, 0x07, 0xa4, 0x30, + 0x39, 0x00, 0x4f, 0x24, 0xc8, 0x30, 0x14, 0x23, + 0x00, 0xdb, 0x30, 0xf3, 0x30, 0xc9, 0x30, 0x14, + 0x2a, 0x00, 0x12, 0x33, 0x22, 0x12, 0x33, 0x2a, + 0xa4, 0x30, 0x3a, 0x00, 0x0b, 0x49, 0xa4, 0x30, + 0x3a, 0x00, 0x47, 0x3a, 0x1f, 0x2b, 0x3a, 0x47, + 0x0b, 0xb7, 0x30, 0x27, 0x3c, 0x00, 0x30, 0x3c, + 0xaf, 0x30, 0x30, 0x00, 0x3e, 0x44, 0xdf, 0x30, + 0xea, 0x30, 0xd0, 0x30, 0x0f, 0x1a, 0x00, 0x2c, + 0x1b, 0xe1, 0x30, 0xac, 0x30, 0xac, 0x30, 0x35, + 0x00, 0x1c, 0x47, 0x35, 0x50, 0x1c, 0x3f, 0xa2, + 0x30, 0x42, 0x5a, 0x27, 0x42, 0x5a, 0x49, 0x44, + 0x00, 0x51, 0xc3, 0x30, 0x27, 0x00, 0x05, 0x28, + 0xea, 0x30, 0xe9, 0x30, 0xd4, 0x30, 0x17, 0x00, + 0x28, 0xd6, 0x30, 0x15, 0x26, 0x00, 0x15, 0xec, + 0x30, 0xe0, 0x30, 0xb2, 0x30, 0x3a, 0x41, 0x16, + 0x00, 0x41, 0xc3, 0x30, 0x2c, 0x00, 0x05, 0x30, + 0x00, 0xb9, 0x70, 0x31, 0x00, 0x30, 0x00, 0xb9, + 0x70, 0x32, 0x00, 0x30, 0x00, 0xb9, 0x70, 0x68, + 0x50, 0x61, 0x64, 0x61, 0x41, 0x55, 0x62, 0x61, + 0x72, 0x6f, 0x56, 0x70, 0x63, 0x64, 0x6d, 0x64, + 0x00, 0x6d, 0x00, 0xb2, 0x00, 0x49, 0x00, 0x55, + 0x00, 0x73, 0x5e, 0x10, 0x62, 0x2d, 0x66, 0x8c, + 0x54, 0x27, 0x59, 0x63, 0x6b, 0x0e, 0x66, 0xbb, + 0x6c, 0x2a, 0x68, 0x0f, 0x5f, 0x1a, 0x4f, 0x3e, + 0x79, 0x70, 0x00, 0x41, 0x6e, 0x00, 0x41, 0xbc, + 0x03, 0x41, 0x6d, 0x00, 0x41, 0x6b, 0x00, 0x41, + 0x4b, 0x00, 0x42, 0x4d, 0x00, 0x42, 0x47, 0x00, + 0x42, 0x63, 0x61, 0x6c, 0x6b, 0x63, 0x61, 0x6c, + 0x70, 0x00, 0x46, 0x6e, 0x00, 0x46, 0xbc, 0x03, + 0x46, 0xbc, 0x03, 0x67, 0x6d, 0x00, 0x67, 0x6b, + 0x00, 0x67, 0x48, 0x00, 0x7a, 0x6b, 0x48, 0x7a, + 0x4d, 0x48, 0x7a, 0x47, 0x48, 0x7a, 0x54, 0x48, + 0x7a, 0xbc, 0x03, 0x13, 0x21, 0x6d, 0x00, 0x13, + 0x21, 0x64, 0x00, 0x13, 0x21, 0x6b, 0x00, 0x13, + 0x21, 0x66, 0x00, 0x6d, 0x6e, 0x00, 0x6d, 0xbc, + 0x03, 0x6d, 0x6d, 0x00, 0x6d, 0x63, 0x00, 0x6d, + 0x6b, 0x00, 0x6d, 0x63, 0x00, 0x0a, 0x0a, 0x4f, + 0x00, 0x0a, 0x4f, 0x6d, 0x00, 0xb2, 0x00, 0x63, + 0x00, 0x08, 0x0a, 0x4f, 0x0a, 0x0a, 0x50, 0x00, + 0x0a, 0x50, 0x6d, 0x00, 0xb3, 0x00, 0x6b, 0x00, + 0x6d, 0x00, 0xb3, 0x00, 0x6d, 0x00, 0x15, 0x22, + 0x73, 0x00, 0x6d, 0x00, 0x15, 0x22, 0x73, 0x00, + 0xb2, 0x00, 0x50, 0x61, 0x6b, 0x50, 0x61, 0x4d, + 0x50, 0x61, 0x47, 0x50, 0x61, 0x72, 0x61, 0x64, + 0x72, 0x61, 0x64, 0xd1, 0x73, 0x72, 0x00, 0x61, + 0x00, 0x64, 0x00, 0x15, 0x22, 0x73, 0x00, 0xb2, + 0x00, 0x70, 0x00, 0x73, 0x6e, 0x00, 0x73, 0xbc, + 0x03, 0x73, 0x6d, 0x00, 0x73, 0x70, 0x00, 0x56, + 0x6e, 0x00, 0x56, 0xbc, 0x03, 0x56, 0x6d, 0x00, + 0x56, 0x6b, 0x00, 0x56, 0x4d, 0x00, 0x56, 0x70, + 0x00, 0x57, 0x6e, 0x00, 0x57, 0xbc, 0x03, 0x57, + 0x6d, 0x00, 0x57, 0x6b, 0x00, 0x57, 0x4d, 0x00, + 0x57, 0x6b, 0x00, 0xa9, 0x03, 0x4d, 0x00, 0xa9, + 0x03, 0x61, 0x2e, 0x6d, 0x2e, 0x42, 0x71, 0x63, + 0x63, 0x63, 0x64, 0x43, 0xd1, 0x6b, 0x67, 0x43, + 0x6f, 0x2e, 0x64, 0x42, 0x47, 0x79, 0x68, 0x61, + 0x48, 0x50, 0x69, 0x6e, 0x4b, 0x4b, 0x4b, 0x4d, + 0x6b, 0x74, 0x6c, 0x6d, 0x6c, 0x6e, 0x6c, 0x6f, + 0x67, 0x6c, 0x78, 0x6d, 0x62, 0x6d, 0x69, 0x6c, + 0x6d, 0x6f, 0x6c, 0x50, 0x48, 0x70, 0x2e, 0x6d, + 0x2e, 0x50, 0x50, 0x4d, 0x50, 0x52, 0x73, 0x72, + 0x53, 0x76, 0x57, 0x62, 0x56, 0xd1, 0x6d, 0x41, + 0xd1, 0x6d, 0x31, 0x00, 0xe5, 0x65, 0x31, 0x00, + 0x30, 0x00, 0xe5, 0x65, 0x32, 0x00, 0x30, 0x00, + 0xe5, 0x65, 0x33, 0x00, 0x30, 0x00, 0xe5, 0x65, + 0x67, 0x61, 0x6c, 0x4a, 0x04, 0x4c, 0x04, 0x43, + 0x46, 0x51, 0x26, 0x01, 0x53, 0x01, 0x27, 0xa7, + 0x37, 0xab, 0x6b, 0x02, 0x52, 0xab, 0x48, 0x8c, + 0xf4, 0x66, 0xca, 0x8e, 0xc8, 0x8c, 0xd1, 0x6e, + 0x32, 0x4e, 0xe5, 0x53, 0x9c, 0x9f, 0x9c, 0x9f, + 0x51, 0x59, 0xd1, 0x91, 0x87, 0x55, 0x48, 0x59, + 0xf6, 0x61, 0x69, 0x76, 0x85, 0x7f, 0x3f, 0x86, + 0xba, 0x87, 0xf8, 0x88, 0x8f, 0x90, 0x02, 0x6a, + 0x1b, 0x6d, 0xd9, 0x70, 0xde, 0x73, 0x3d, 0x84, + 0x6a, 0x91, 0xf1, 0x99, 0x82, 0x4e, 0x75, 0x53, + 0x04, 0x6b, 0x1b, 0x72, 0x2d, 0x86, 0x1e, 0x9e, + 0x50, 0x5d, 0xeb, 0x6f, 0xcd, 0x85, 0x64, 0x89, + 0xc9, 0x62, 0xd8, 0x81, 0x1f, 0x88, 0xca, 0x5e, + 0x17, 0x67, 0x6a, 0x6d, 0xfc, 0x72, 0xce, 0x90, + 0x86, 0x4f, 0xb7, 0x51, 0xde, 0x52, 0xc4, 0x64, + 0xd3, 0x6a, 0x10, 0x72, 0xe7, 0x76, 0x01, 0x80, + 0x06, 0x86, 0x5c, 0x86, 0xef, 0x8d, 0x32, 0x97, + 0x6f, 0x9b, 0xfa, 0x9d, 0x8c, 0x78, 0x7f, 0x79, + 0xa0, 0x7d, 0xc9, 0x83, 0x04, 0x93, 0x7f, 0x9e, + 0xd6, 0x8a, 0xdf, 0x58, 0x04, 0x5f, 0x60, 0x7c, + 0x7e, 0x80, 0x62, 0x72, 0xca, 0x78, 0xc2, 0x8c, + 0xf7, 0x96, 0xd8, 0x58, 0x62, 0x5c, 0x13, 0x6a, + 0xda, 0x6d, 0x0f, 0x6f, 0x2f, 0x7d, 0x37, 0x7e, + 0x4b, 0x96, 0xd2, 0x52, 0x8b, 0x80, 0xdc, 0x51, + 0xcc, 0x51, 0x1c, 0x7a, 0xbe, 0x7d, 0xf1, 0x83, + 0x75, 0x96, 0x80, 0x8b, 0xcf, 0x62, 0x02, 0x6a, + 0xfe, 0x8a, 0x39, 0x4e, 0xe7, 0x5b, 0x12, 0x60, + 0x87, 0x73, 0x70, 0x75, 0x17, 0x53, 0xfb, 0x78, + 0xbf, 0x4f, 0xa9, 0x5f, 0x0d, 0x4e, 0xcc, 0x6c, + 0x78, 0x65, 0x22, 0x7d, 0xc3, 0x53, 0x5e, 0x58, + 0x01, 0x77, 0x49, 0x84, 0xaa, 0x8a, 0xba, 0x6b, + 0xb0, 0x8f, 0x88, 0x6c, 0xfe, 0x62, 0xe5, 0x82, + 0xa0, 0x63, 0x65, 0x75, 0xae, 0x4e, 0x69, 0x51, + 0xc9, 0x51, 0x81, 0x68, 0xe7, 0x7c, 0x6f, 0x82, + 0xd2, 0x8a, 0xcf, 0x91, 0xf5, 0x52, 0x42, 0x54, + 0x73, 0x59, 0xec, 0x5e, 0xc5, 0x65, 0xfe, 0x6f, + 0x2a, 0x79, 0xad, 0x95, 0x6a, 0x9a, 0x97, 0x9e, + 0xce, 0x9e, 0x9b, 0x52, 0xc6, 0x66, 0x77, 0x6b, + 0x62, 0x8f, 0x74, 0x5e, 0x90, 0x61, 0x00, 0x62, + 0x9a, 0x64, 0x23, 0x6f, 0x49, 0x71, 0x89, 0x74, + 0xca, 0x79, 0xf4, 0x7d, 0x6f, 0x80, 0x26, 0x8f, + 0xee, 0x84, 0x23, 0x90, 0x4a, 0x93, 0x17, 0x52, + 0xa3, 0x52, 0xbd, 0x54, 0xc8, 0x70, 0xc2, 0x88, + 0xaa, 0x8a, 0xc9, 0x5e, 0xf5, 0x5f, 0x7b, 0x63, + 0xae, 0x6b, 0x3e, 0x7c, 0x75, 0x73, 0xe4, 0x4e, + 0xf9, 0x56, 0xe7, 0x5b, 0xba, 0x5d, 0x1c, 0x60, + 0xb2, 0x73, 0x69, 0x74, 0x9a, 0x7f, 0x46, 0x80, + 0x34, 0x92, 0xf6, 0x96, 0x48, 0x97, 0x18, 0x98, + 0x8b, 0x4f, 0xae, 0x79, 0xb4, 0x91, 0xb8, 0x96, + 0xe1, 0x60, 0x86, 0x4e, 0xda, 0x50, 0xee, 0x5b, + 0x3f, 0x5c, 0x99, 0x65, 0x02, 0x6a, 0xce, 0x71, + 0x42, 0x76, 0xfc, 0x84, 0x7c, 0x90, 0x8d, 0x9f, + 0x88, 0x66, 0x2e, 0x96, 0x89, 0x52, 0x7b, 0x67, + 0xf3, 0x67, 0x41, 0x6d, 0x9c, 0x6e, 0x09, 0x74, + 0x59, 0x75, 0x6b, 0x78, 0x10, 0x7d, 0x5e, 0x98, + 0x6d, 0x51, 0x2e, 0x62, 0x78, 0x96, 0x2b, 0x50, + 0x19, 0x5d, 0xea, 0x6d, 0x2a, 0x8f, 0x8b, 0x5f, + 0x44, 0x61, 0x17, 0x68, 0x87, 0x73, 0x86, 0x96, + 0x29, 0x52, 0x0f, 0x54, 0x65, 0x5c, 0x13, 0x66, + 0x4e, 0x67, 0xa8, 0x68, 0xe5, 0x6c, 0x06, 0x74, + 0xe2, 0x75, 0x79, 0x7f, 0xcf, 0x88, 0xe1, 0x88, + 0xcc, 0x91, 0xe2, 0x96, 0x3f, 0x53, 0xba, 0x6e, + 0x1d, 0x54, 0xd0, 0x71, 0x98, 0x74, 0xfa, 0x85, + 0xa3, 0x96, 0x57, 0x9c, 0x9f, 0x9e, 0x97, 0x67, + 0xcb, 0x6d, 0xe8, 0x81, 0xcb, 0x7a, 0x20, 0x7b, + 0x92, 0x7c, 0xc0, 0x72, 0x99, 0x70, 0x58, 0x8b, + 0xc0, 0x4e, 0x36, 0x83, 0x3a, 0x52, 0x07, 0x52, + 0xa6, 0x5e, 0xd3, 0x62, 0xd6, 0x7c, 0x85, 0x5b, + 0x1e, 0x6d, 0xb4, 0x66, 0x3b, 0x8f, 0x4c, 0x88, + 0x4d, 0x96, 0x8b, 0x89, 0xd3, 0x5e, 0x40, 0x51, + 0xc0, 0x55, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x58, + 0x00, 0x00, 0x74, 0x66, 0x00, 0x00, 0x00, 0x00, + 0xde, 0x51, 0x2a, 0x73, 0xca, 0x76, 0x3c, 0x79, + 0x5e, 0x79, 0x65, 0x79, 0x8f, 0x79, 0x56, 0x97, + 0xbe, 0x7c, 0xbd, 0x7f, 0x00, 0x00, 0x12, 0x86, + 0x00, 0x00, 0xf8, 0x8a, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x90, 0xfd, 0x90, 0xef, 0x98, 0xfc, 0x98, + 0x28, 0x99, 0xb4, 0x9d, 0xde, 0x90, 0xb7, 0x96, + 0xae, 0x4f, 0xe7, 0x50, 0x4d, 0x51, 0xc9, 0x52, + 0xe4, 0x52, 0x51, 0x53, 0x9d, 0x55, 0x06, 0x56, + 0x68, 0x56, 0x40, 0x58, 0xa8, 0x58, 0x64, 0x5c, + 0x6e, 0x5c, 0x94, 0x60, 0x68, 0x61, 0x8e, 0x61, + 0xf2, 0x61, 0x4f, 0x65, 0xe2, 0x65, 0x91, 0x66, + 0x85, 0x68, 0x77, 0x6d, 0x1a, 0x6e, 0x22, 0x6f, + 0x6e, 0x71, 0x2b, 0x72, 0x22, 0x74, 0x91, 0x78, + 0x3e, 0x79, 0x49, 0x79, 0x48, 0x79, 0x50, 0x79, + 0x56, 0x79, 0x5d, 0x79, 0x8d, 0x79, 0x8e, 0x79, + 0x40, 0x7a, 0x81, 0x7a, 0xc0, 0x7b, 0xf4, 0x7d, + 0x09, 0x7e, 0x41, 0x7e, 0x72, 0x7f, 0x05, 0x80, + 0xed, 0x81, 0x79, 0x82, 0x79, 0x82, 0x57, 0x84, + 0x10, 0x89, 0x96, 0x89, 0x01, 0x8b, 0x39, 0x8b, + 0xd3, 0x8c, 0x08, 0x8d, 0xb6, 0x8f, 0x38, 0x90, + 0xe3, 0x96, 0xff, 0x97, 0x3b, 0x98, 0x75, 0x60, + 0xee, 0x42, 0x18, 0x82, 0x02, 0x26, 0x4e, 0xb5, + 0x51, 0x68, 0x51, 0x80, 0x4f, 0x45, 0x51, 0x80, + 0x51, 0xc7, 0x52, 0xfa, 0x52, 0x9d, 0x55, 0x55, + 0x55, 0x99, 0x55, 0xe2, 0x55, 0x5a, 0x58, 0xb3, + 0x58, 0x44, 0x59, 0x54, 0x59, 0x62, 0x5a, 0x28, + 0x5b, 0xd2, 0x5e, 0xd9, 0x5e, 0x69, 0x5f, 0xad, + 0x5f, 0xd8, 0x60, 0x4e, 0x61, 0x08, 0x61, 0x8e, + 0x61, 0x60, 0x61, 0xf2, 0x61, 0x34, 0x62, 0xc4, + 0x63, 0x1c, 0x64, 0x52, 0x64, 0x56, 0x65, 0x74, + 0x66, 0x17, 0x67, 0x1b, 0x67, 0x56, 0x67, 0x79, + 0x6b, 0xba, 0x6b, 0x41, 0x6d, 0xdb, 0x6e, 0xcb, + 0x6e, 0x22, 0x6f, 0x1e, 0x70, 0x6e, 0x71, 0xa7, + 0x77, 0x35, 0x72, 0xaf, 0x72, 0x2a, 0x73, 0x71, + 0x74, 0x06, 0x75, 0x3b, 0x75, 0x1d, 0x76, 0x1f, + 0x76, 0xca, 0x76, 0xdb, 0x76, 0xf4, 0x76, 0x4a, + 0x77, 0x40, 0x77, 0xcc, 0x78, 0xb1, 0x7a, 0xc0, + 0x7b, 0x7b, 0x7c, 0x5b, 0x7d, 0xf4, 0x7d, 0x3e, + 0x7f, 0x05, 0x80, 0x52, 0x83, 0xef, 0x83, 0x79, + 0x87, 0x41, 0x89, 0x86, 0x89, 0x96, 0x89, 0xbf, + 0x8a, 0xf8, 0x8a, 0xcb, 0x8a, 0x01, 0x8b, 0xfe, + 0x8a, 0xed, 0x8a, 0x39, 0x8b, 0x8a, 0x8b, 0x08, + 0x8d, 0x38, 0x8f, 0x72, 0x90, 0x99, 0x91, 0x76, + 0x92, 0x7c, 0x96, 0xe3, 0x96, 0x56, 0x97, 0xdb, + 0x97, 0xff, 0x97, 0x0b, 0x98, 0x3b, 0x98, 0x12, + 0x9b, 0x9c, 0x9f, 0x4a, 0x28, 0x44, 0x28, 0xd5, + 0x33, 0x9d, 0x3b, 0x18, 0x40, 0x39, 0x40, 0x49, + 0x52, 0xd0, 0x5c, 0xd3, 0x7e, 0x43, 0x9f, 0x8e, + 0x9f, 0x2a, 0xa0, 0x02, 0x66, 0x66, 0x66, 0x69, + 0x66, 0x6c, 0x66, 0x66, 0x69, 0x66, 0x66, 0x6c, + 0x7f, 0x01, 0x74, 0x73, 0x00, 0x74, 0x65, 0x05, + 0x0f, 0x11, 0x0f, 0x00, 0x0f, 0x06, 0x19, 0x11, + 0x0f, 0x08, 0xd9, 0x05, 0xb4, 0x05, 0x00, 0x00, + 0x00, 0x00, 0xf2, 0x05, 0xb7, 0x05, 0xd0, 0x05, + 0x12, 0x00, 0x03, 0x04, 0x0b, 0x0c, 0x0d, 0x18, + 0x1a, 0xe9, 0x05, 0xc1, 0x05, 0xe9, 0x05, 0xc2, + 0x05, 0x49, 0xfb, 0xc1, 0x05, 0x49, 0xfb, 0xc2, + 0x05, 0xd0, 0x05, 0xb7, 0x05, 0xd0, 0x05, 0xb8, + 0x05, 0xd0, 0x05, 0xbc, 0x05, 0xd8, 0x05, 0xbc, + 0x05, 0xde, 0x05, 0xbc, 0x05, 0xe0, 0x05, 0xbc, + 0x05, 0xe3, 0x05, 0xbc, 0x05, 0xb9, 0x05, 0x2d, + 0x03, 0x2e, 0x03, 0x2f, 0x03, 0x30, 0x03, 0x31, + 0x03, 0x1c, 0x00, 0x18, 0x06, 0x22, 0x06, 0x2b, + 0x06, 0xd0, 0x05, 0xdc, 0x05, 0x71, 0x06, 0x00, + 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0f, 0x0f, 0x0f, 0x0f, 0x09, 0x09, 0x09, + 0x09, 0x0e, 0x0e, 0x0e, 0x0e, 0x08, 0x08, 0x08, + 0x08, 0x33, 0x33, 0x33, 0x33, 0x35, 0x35, 0x35, + 0x35, 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, + 0x12, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, + 0x16, 0x1c, 0x1c, 0x1b, 0x1b, 0x1d, 0x1d, 0x17, + 0x17, 0x27, 0x27, 0x20, 0x20, 0x38, 0x38, 0x38, + 0x38, 0x3e, 0x3e, 0x3e, 0x3e, 0x42, 0x42, 0x42, + 0x42, 0x40, 0x40, 0x40, 0x40, 0x49, 0x49, 0x4a, + 0x4a, 0x4a, 0x4a, 0x4f, 0x4f, 0x50, 0x50, 0x50, + 0x50, 0x4d, 0x4d, 0x4d, 0x4d, 0x61, 0x61, 0x62, + 0x62, 0x49, 0x06, 0x64, 0x64, 0x64, 0x64, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7f, 0x7f, 0x2e, 0x82, 0x82, + 0x7c, 0x7c, 0x80, 0x80, 0x87, 0x87, 0x87, 0x87, + 0x00, 0x00, 0x26, 0x06, 0x00, 0x01, 0x00, 0x01, + 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x22, 0x00, 0x22, + 0x00, 0xa1, 0x00, 0xa1, 0x00, 0xa0, 0x00, 0xa0, + 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xaa, + 0x00, 0xaa, 0x00, 0x23, 0x00, 0x23, 0x00, 0x23, + 0xcc, 0x06, 0x00, 0x00, 0x00, 0x00, 0x26, 0x06, + 0x00, 0x06, 0x00, 0x07, 0x00, 0x1f, 0x00, 0x23, + 0x00, 0x24, 0x02, 0x06, 0x02, 0x07, 0x02, 0x08, + 0x02, 0x1f, 0x02, 0x23, 0x02, 0x24, 0x04, 0x06, + 0x04, 0x07, 0x04, 0x08, 0x04, 0x1f, 0x04, 0x23, + 0x04, 0x24, 0x05, 0x06, 0x05, 0x1f, 0x05, 0x23, + 0x05, 0x24, 0x06, 0x07, 0x06, 0x1f, 0x07, 0x06, + 0x07, 0x1f, 0x08, 0x06, 0x08, 0x07, 0x08, 0x1f, + 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x08, 0x0d, 0x1f, + 0x0f, 0x07, 0x0f, 0x1f, 0x10, 0x06, 0x10, 0x07, + 0x10, 0x08, 0x10, 0x1f, 0x11, 0x07, 0x11, 0x1f, + 0x12, 0x1f, 0x13, 0x06, 0x13, 0x1f, 0x14, 0x06, + 0x14, 0x1f, 0x1b, 0x06, 0x1b, 0x07, 0x1b, 0x08, + 0x1b, 0x1f, 0x1b, 0x23, 0x1b, 0x24, 0x1c, 0x07, + 0x1c, 0x1f, 0x1c, 0x23, 0x1c, 0x24, 0x1d, 0x01, + 0x1d, 0x06, 0x1d, 0x07, 0x1d, 0x08, 0x1d, 0x1e, + 0x1d, 0x1f, 0x1d, 0x23, 0x1d, 0x24, 0x1e, 0x06, + 0x1e, 0x07, 0x1e, 0x08, 0x1e, 0x1f, 0x1e, 0x23, + 0x1e, 0x24, 0x1f, 0x06, 0x1f, 0x07, 0x1f, 0x08, + 0x1f, 0x1f, 0x1f, 0x23, 0x1f, 0x24, 0x20, 0x06, + 0x20, 0x07, 0x20, 0x08, 0x20, 0x1f, 0x20, 0x23, + 0x20, 0x24, 0x21, 0x06, 0x21, 0x1f, 0x21, 0x23, + 0x21, 0x24, 0x24, 0x06, 0x24, 0x07, 0x24, 0x08, + 0x24, 0x1f, 0x24, 0x23, 0x24, 0x24, 0x0a, 0x4a, + 0x0b, 0x4a, 0x23, 0x4a, 0x20, 0x00, 0x4c, 0x06, + 0x51, 0x06, 0x51, 0x06, 0xff, 0x00, 0x1f, 0x26, + 0x06, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x1f, 0x00, + 0x20, 0x00, 0x23, 0x00, 0x24, 0x02, 0x0b, 0x02, + 0x0c, 0x02, 0x1f, 0x02, 0x20, 0x02, 0x23, 0x02, + 0x24, 0x04, 0x0b, 0x04, 0x0c, 0x04, 0x1f, 0x26, + 0x06, 0x04, 0x20, 0x04, 0x23, 0x04, 0x24, 0x05, + 0x0b, 0x05, 0x0c, 0x05, 0x1f, 0x05, 0x20, 0x05, + 0x23, 0x05, 0x24, 0x1b, 0x23, 0x1b, 0x24, 0x1c, + 0x23, 0x1c, 0x24, 0x1d, 0x01, 0x1d, 0x1e, 0x1d, + 0x1f, 0x1d, 0x23, 0x1d, 0x24, 0x1e, 0x1f, 0x1e, + 0x23, 0x1e, 0x24, 0x1f, 0x01, 0x1f, 0x1f, 0x20, + 0x0b, 0x20, 0x0c, 0x20, 0x1f, 0x20, 0x20, 0x20, + 0x23, 0x20, 0x24, 0x23, 0x4a, 0x24, 0x0b, 0x24, + 0x0c, 0x24, 0x1f, 0x24, 0x20, 0x24, 0x23, 0x24, + 0x24, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x1f, 0x00, 0x21, 0x02, 0x06, 0x02, 0x07, 0x02, + 0x08, 0x02, 0x1f, 0x02, 0x21, 0x04, 0x06, 0x04, + 0x07, 0x04, 0x08, 0x04, 0x1f, 0x04, 0x21, 0x05, + 0x1f, 0x06, 0x07, 0x06, 0x1f, 0x07, 0x06, 0x07, + 0x1f, 0x08, 0x06, 0x08, 0x1f, 0x0d, 0x06, 0x0d, + 0x07, 0x0d, 0x08, 0x0d, 0x1f, 0x0f, 0x07, 0x0f, + 0x08, 0x0f, 0x1f, 0x10, 0x06, 0x10, 0x07, 0x10, + 0x08, 0x10, 0x1f, 0x11, 0x07, 0x12, 0x1f, 0x13, + 0x06, 0x13, 0x1f, 0x14, 0x06, 0x14, 0x1f, 0x1b, + 0x06, 0x1b, 0x07, 0x1b, 0x08, 0x1b, 0x1f, 0x1c, + 0x07, 0x1c, 0x1f, 0x1d, 0x06, 0x1d, 0x07, 0x1d, + 0x08, 0x1d, 0x1e, 0x1d, 0x1f, 0x1e, 0x06, 0x1e, + 0x07, 0x1e, 0x08, 0x1e, 0x1f, 0x1e, 0x21, 0x1f, + 0x06, 0x1f, 0x07, 0x1f, 0x08, 0x1f, 0x1f, 0x20, + 0x06, 0x20, 0x07, 0x20, 0x08, 0x20, 0x1f, 0x20, + 0x21, 0x21, 0x06, 0x21, 0x1f, 0x21, 0x4a, 0x24, + 0x06, 0x24, 0x07, 0x24, 0x08, 0x24, 0x1f, 0x24, + 0x21, 0x00, 0x1f, 0x00, 0x21, 0x02, 0x1f, 0x02, + 0x21, 0x04, 0x1f, 0x04, 0x21, 0x05, 0x1f, 0x05, + 0x21, 0x0d, 0x1f, 0x0d, 0x21, 0x0e, 0x1f, 0x0e, + 0x21, 0x1d, 0x1e, 0x1d, 0x1f, 0x1e, 0x1f, 0x20, + 0x1f, 0x20, 0x21, 0x24, 0x1f, 0x24, 0x21, 0x40, + 0x06, 0x4e, 0x06, 0x51, 0x06, 0x27, 0x06, 0x10, + 0x22, 0x10, 0x23, 0x12, 0x22, 0x12, 0x23, 0x13, + 0x22, 0x13, 0x23, 0x0c, 0x22, 0x0c, 0x23, 0x0d, + 0x22, 0x0d, 0x23, 0x06, 0x22, 0x06, 0x23, 0x05, + 0x22, 0x05, 0x23, 0x07, 0x22, 0x07, 0x23, 0x0e, + 0x22, 0x0e, 0x23, 0x0f, 0x22, 0x0f, 0x23, 0x0d, + 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, 0x0d, + 0x0a, 0x0c, 0x0a, 0x0e, 0x0a, 0x0f, 0x0a, 0x10, + 0x22, 0x10, 0x23, 0x12, 0x22, 0x12, 0x23, 0x13, + 0x22, 0x13, 0x23, 0x0c, 0x22, 0x0c, 0x23, 0x0d, + 0x22, 0x0d, 0x23, 0x06, 0x22, 0x06, 0x23, 0x05, + 0x22, 0x05, 0x23, 0x07, 0x22, 0x07, 0x23, 0x0e, + 0x22, 0x0e, 0x23, 0x0f, 0x22, 0x0f, 0x23, 0x0d, + 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, 0x0d, + 0x0a, 0x0c, 0x0a, 0x0e, 0x0a, 0x0f, 0x0a, 0x0d, + 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, 0x0c, + 0x20, 0x0d, 0x20, 0x10, 0x1e, 0x0c, 0x05, 0x0c, + 0x06, 0x0c, 0x07, 0x0d, 0x05, 0x0d, 0x06, 0x0d, + 0x07, 0x10, 0x1e, 0x11, 0x1e, 0x00, 0x24, 0x00, + 0x24, 0x2a, 0x06, 0x00, 0x02, 0x1b, 0x00, 0x03, + 0x02, 0x00, 0x03, 0x02, 0x00, 0x03, 0x1b, 0x00, + 0x04, 0x1b, 0x00, 0x1b, 0x02, 0x00, 0x1b, 0x03, + 0x00, 0x1b, 0x04, 0x02, 0x1b, 0x03, 0x02, 0x1b, + 0x03, 0x03, 0x1b, 0x20, 0x03, 0x1b, 0x1f, 0x09, + 0x03, 0x02, 0x09, 0x02, 0x03, 0x09, 0x02, 0x1f, + 0x09, 0x1b, 0x03, 0x09, 0x1b, 0x03, 0x09, 0x1b, + 0x02, 0x09, 0x1b, 0x1b, 0x09, 0x1b, 0x1b, 0x0b, + 0x03, 0x03, 0x0b, 0x03, 0x03, 0x0b, 0x1b, 0x1b, + 0x0a, 0x03, 0x1b, 0x0a, 0x03, 0x1b, 0x0a, 0x02, + 0x20, 0x0a, 0x1b, 0x04, 0x0a, 0x1b, 0x04, 0x0a, + 0x1b, 0x1b, 0x0a, 0x1b, 0x1b, 0x0c, 0x03, 0x1f, + 0x0c, 0x04, 0x1b, 0x0c, 0x04, 0x1b, 0x0d, 0x1b, + 0x03, 0x0d, 0x1b, 0x03, 0x0d, 0x1b, 0x1b, 0x0d, + 0x1b, 0x20, 0x0f, 0x02, 0x1b, 0x0f, 0x1b, 0x1b, + 0x0f, 0x1b, 0x1b, 0x0f, 0x1b, 0x1f, 0x10, 0x1b, + 0x1b, 0x10, 0x1b, 0x20, 0x10, 0x1b, 0x1f, 0x17, + 0x04, 0x1b, 0x17, 0x04, 0x1b, 0x18, 0x1b, 0x03, + 0x18, 0x1b, 0x1b, 0x1a, 0x03, 0x1b, 0x1a, 0x03, + 0x20, 0x1a, 0x03, 0x1f, 0x1a, 0x02, 0x02, 0x1a, + 0x02, 0x02, 0x1a, 0x04, 0x1b, 0x1a, 0x04, 0x1b, + 0x1a, 0x1b, 0x03, 0x1a, 0x1b, 0x03, 0x1b, 0x03, + 0x02, 0x1b, 0x03, 0x1b, 0x1b, 0x03, 0x20, 0x1b, + 0x02, 0x03, 0x1b, 0x02, 0x1b, 0x1b, 0x04, 0x02, + 0x1b, 0x04, 0x1b, 0x28, 0x06, 0x1d, 0x04, 0x06, + 0x1f, 0x1d, 0x04, 0x1f, 0x1d, 0x1d, 0x1e, 0x05, + 0x1d, 0x1e, 0x05, 0x21, 0x1e, 0x04, 0x1d, 0x1e, + 0x04, 0x1d, 0x1e, 0x04, 0x21, 0x1e, 0x1d, 0x22, + 0x1e, 0x1d, 0x21, 0x22, 0x1d, 0x1d, 0x22, 0x1d, + 0x1d, 0x00, 0x06, 0x22, 0x02, 0x04, 0x22, 0x02, + 0x04, 0x21, 0x02, 0x06, 0x22, 0x02, 0x06, 0x21, + 0x02, 0x1d, 0x22, 0x02, 0x1d, 0x21, 0x04, 0x1d, + 0x22, 0x04, 0x05, 0x21, 0x04, 0x1d, 0x21, 0x0b, + 0x06, 0x21, 0x0d, 0x05, 0x22, 0x0c, 0x05, 0x22, + 0x0e, 0x05, 0x22, 0x1c, 0x04, 0x22, 0x1c, 0x1d, + 0x22, 0x22, 0x05, 0x22, 0x22, 0x04, 0x22, 0x22, + 0x1d, 0x22, 0x1d, 0x1d, 0x22, 0x1a, 0x1d, 0x22, + 0x1e, 0x05, 0x22, 0x1a, 0x1d, 0x05, 0x1c, 0x05, + 0x1d, 0x11, 0x1d, 0x22, 0x1b, 0x1d, 0x22, 0x1e, + 0x04, 0x05, 0x1d, 0x06, 0x22, 0x1c, 0x04, 0x1d, + 0x1b, 0x1d, 0x1d, 0x1c, 0x04, 0x1d, 0x1e, 0x04, + 0x05, 0x04, 0x05, 0x22, 0x05, 0x04, 0x22, 0x1d, + 0x04, 0x22, 0x19, 0x1d, 0x22, 0x00, 0x05, 0x22, + 0x1b, 0x1d, 0x1d, 0x11, 0x04, 0x1d, 0x0d, 0x1d, + 0x1d, 0x0b, 0x06, 0x22, 0x1e, 0x04, 0x22, 0x35, + 0x06, 0x00, 0x0f, 0x9d, 0x0d, 0x0f, 0x9d, 0x27, + 0x06, 0x00, 0x1d, 0x1d, 0x20, 0x00, 0x1c, 0x01, + 0x0a, 0x1e, 0x06, 0x1e, 0x08, 0x0e, 0x1d, 0x12, + 0x1e, 0x0a, 0x0c, 0x21, 0x1d, 0x12, 0x1d, 0x23, + 0x20, 0x21, 0x0c, 0x1d, 0x1e, 0x35, 0x06, 0x00, + 0x0f, 0x14, 0x27, 0x06, 0x0e, 0x1d, 0x22, 0xff, + 0x00, 0x1d, 0x1d, 0x20, 0xff, 0x12, 0x1d, 0x23, + 0x20, 0xff, 0x21, 0x0c, 0x1d, 0x1e, 0x27, 0x06, + 0x05, 0x1d, 0xff, 0x05, 0x1d, 0x00, 0x1d, 0x20, + 0x27, 0x06, 0x0a, 0xa5, 0x00, 0x1d, 0x2c, 0x00, + 0x01, 0x30, 0x02, 0x30, 0x3a, 0x00, 0x3b, 0x00, + 0x21, 0x00, 0x3f, 0x00, 0x16, 0x30, 0x17, 0x30, + 0x26, 0x20, 0x13, 0x20, 0x12, 0x01, 0x00, 0x5f, + 0x5f, 0x28, 0x29, 0x7b, 0x7d, 0x08, 0x30, 0x0c, + 0x0d, 0x08, 0x09, 0x02, 0x03, 0x00, 0x01, 0x04, + 0x05, 0x06, 0x07, 0x5b, 0x00, 0x5d, 0x00, 0x3e, + 0x20, 0x3e, 0x20, 0x3e, 0x20, 0x3e, 0x20, 0x5f, + 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x2c, 0x00, 0x01, + 0x30, 0x2e, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x3a, + 0x00, 0x3f, 0x00, 0x21, 0x00, 0x14, 0x20, 0x28, + 0x00, 0x29, 0x00, 0x7b, 0x00, 0x7d, 0x00, 0x14, + 0x30, 0x15, 0x30, 0x23, 0x26, 0x2a, 0x2b, 0x2d, + 0x3c, 0x3e, 0x3d, 0x00, 0x5c, 0x24, 0x25, 0x40, + 0x40, 0x06, 0xff, 0x0b, 0x00, 0x0b, 0xff, 0x0c, + 0x20, 0x00, 0x4d, 0x06, 0x40, 0x06, 0xff, 0x0e, + 0x00, 0x0e, 0xff, 0x0f, 0x00, 0x0f, 0xff, 0x10, + 0x00, 0x10, 0xff, 0x11, 0x00, 0x11, 0xff, 0x12, + 0x00, 0x12, 0x21, 0x06, 0x00, 0x01, 0x01, 0x02, + 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, + 0x05, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, + 0x08, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, + 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, + 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, + 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, + 0x16, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, + 0x18, 0x19, 0x19, 0x19, 0x19, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, + 0x22, 0x23, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, + 0x24, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26, + 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x29, + 0x29, 0x22, 0x06, 0x22, 0x00, 0x22, 0x00, 0x22, + 0x01, 0x22, 0x01, 0x22, 0x03, 0x22, 0x03, 0x22, + 0x05, 0x22, 0x05, 0x21, 0x00, 0x85, 0x29, 0x01, + 0x30, 0x01, 0x0b, 0x0c, 0x00, 0xfa, 0xf1, 0xa0, + 0xa2, 0xa4, 0xa6, 0xa8, 0xe2, 0xe4, 0xe6, 0xc2, + 0xfb, 0xa1, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, + 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, + 0xbe, 0xc0, 0xc3, 0xc5, 0xc7, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xd1, 0xd4, 0xd7, 0xda, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe3, 0xe5, 0xe7, 0xe8, + 0xe9, 0xea, 0xeb, 0xec, 0xee, 0xf2, 0x98, 0x99, + 0x31, 0x31, 0x4f, 0x31, 0x55, 0x31, 0x5b, 0x31, + 0x61, 0x31, 0xa2, 0x00, 0xa3, 0x00, 0xac, 0x00, + 0xaf, 0x00, 0xa6, 0x00, 0xa5, 0x00, 0xa9, 0x20, + 0x00, 0x00, 0x02, 0x25, 0x90, 0x21, 0x91, 0x21, + 0x92, 0x21, 0x93, 0x21, 0xa0, 0x25, 0xcb, 0x25, + 0xd0, 0x02, 0xd1, 0x02, 0xe6, 0x00, 0x99, 0x02, + 0x53, 0x02, 0x00, 0x00, 0xa3, 0x02, 0x66, 0xab, + 0xa5, 0x02, 0xa4, 0x02, 0x56, 0x02, 0x57, 0x02, + 0x91, 0x1d, 0x58, 0x02, 0x5e, 0x02, 0xa9, 0x02, + 0x64, 0x02, 0x62, 0x02, 0x60, 0x02, 0x9b, 0x02, + 0x27, 0x01, 0x9c, 0x02, 0x67, 0x02, 0x84, 0x02, + 0xaa, 0x02, 0xab, 0x02, 0x6c, 0x02, 0x04, 0xdf, + 0x8e, 0xa7, 0x6e, 0x02, 0x05, 0xdf, 0x8e, 0x02, + 0x06, 0xdf, 0xf8, 0x00, 0x76, 0x02, 0x77, 0x02, + 0x71, 0x00, 0x7a, 0x02, 0x08, 0xdf, 0x7d, 0x02, + 0x7e, 0x02, 0x80, 0x02, 0xa8, 0x02, 0xa6, 0x02, + 0x67, 0xab, 0xa7, 0x02, 0x88, 0x02, 0x71, 0x2c, + 0x00, 0x00, 0x8f, 0x02, 0xa1, 0x02, 0xa2, 0x02, + 0x98, 0x02, 0xc0, 0x01, 0xc1, 0x01, 0xc2, 0x01, + 0x0a, 0xdf, 0x1e, 0xdf, 0x41, 0x04, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x14, 0x99, 0x10, 0xba, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x9b, 0x10, 0xba, 0x10, + 0x05, 0x05, 0xa5, 0x10, 0xba, 0x10, 0x05, 0x31, + 0x11, 0x27, 0x11, 0x32, 0x11, 0x27, 0x11, 0x55, + 0x47, 0x13, 0x3e, 0x13, 0x47, 0x13, 0x57, 0x13, + 0x55, 0xb9, 0x14, 0xba, 0x14, 0xb9, 0x14, 0xb0, + 0x14, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x14, 0xbd, + 0x14, 0x55, 0x50, 0xb8, 0x15, 0xaf, 0x15, 0xb9, + 0x15, 0xaf, 0x15, 0x55, 0x35, 0x19, 0x30, 0x19, + 0x05, 0x57, 0xd1, 0x65, 0xd1, 0x58, 0xd1, 0x65, + 0xd1, 0x5f, 0xd1, 0x6e, 0xd1, 0x5f, 0xd1, 0x6f, + 0xd1, 0x5f, 0xd1, 0x70, 0xd1, 0x5f, 0xd1, 0x71, + 0xd1, 0x5f, 0xd1, 0x72, 0xd1, 0x55, 0x55, 0x55, + 0x05, 0xb9, 0xd1, 0x65, 0xd1, 0xba, 0xd1, 0x65, + 0xd1, 0xbb, 0xd1, 0x6e, 0xd1, 0xbc, 0xd1, 0x6e, + 0xd1, 0xbb, 0xd1, 0x6f, 0xd1, 0xbc, 0xd1, 0x6f, + 0xd1, 0x55, 0x55, 0x55, 0x41, 0x00, 0x61, 0x00, + 0x41, 0x00, 0x61, 0x00, 0x69, 0x00, 0x41, 0x00, + 0x61, 0x00, 0x41, 0x00, 0x43, 0x44, 0x00, 0x00, + 0x47, 0x00, 0x00, 0x4a, 0x4b, 0x00, 0x00, 0x4e, + 0x4f, 0x50, 0x51, 0x00, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, + 0x00, 0x66, 0x68, 0x00, 0x70, 0x00, 0x41, 0x00, + 0x61, 0x00, 0x41, 0x42, 0x00, 0x44, 0x45, 0x46, + 0x47, 0x4a, 0x00, 0x53, 0x00, 0x61, 0x00, 0x41, + 0x42, 0x00, 0x44, 0x45, 0x46, 0x47, 0x00, 0x49, + 0x4a, 0x4b, 0x4c, 0x4d, 0x00, 0x4f, 0x53, 0x00, + 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, + 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, + 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, + 0x61, 0x00, 0x31, 0x01, 0x37, 0x02, 0x91, 0x03, + 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, + 0x1f, 0x04, 0x20, 0x05, 0x91, 0x03, 0xa3, 0x03, + 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, + 0x20, 0x05, 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, + 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, + 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, + 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, 0x91, 0x03, + 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, + 0x1f, 0x04, 0x20, 0x05, 0x0b, 0x0c, 0x30, 0x00, + 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, + 0x27, 0x06, 0x00, 0x01, 0x05, 0x08, 0x2a, 0x06, + 0x1e, 0x08, 0x03, 0x0d, 0x20, 0x19, 0x1a, 0x1b, + 0x1c, 0x09, 0x0f, 0x17, 0x0b, 0x18, 0x07, 0x0a, + 0x00, 0x01, 0x04, 0x06, 0x0c, 0x0e, 0x10, 0x44, + 0x90, 0x77, 0x45, 0x28, 0x06, 0x2c, 0x06, 0x00, + 0x00, 0x47, 0x06, 0x33, 0x06, 0x17, 0x10, 0x11, + 0x12, 0x13, 0x00, 0x06, 0x0e, 0x02, 0x0f, 0x34, + 0x06, 0x2a, 0x06, 0x2b, 0x06, 0x2e, 0x06, 0x00, + 0x00, 0x36, 0x06, 0x00, 0x00, 0x3a, 0x06, 0x2d, + 0x06, 0x00, 0x00, 0x4a, 0x06, 0x00, 0x00, 0x44, + 0x06, 0x00, 0x00, 0x46, 0x06, 0x33, 0x06, 0x39, + 0x06, 0x00, 0x00, 0x35, 0x06, 0x42, 0x06, 0x00, + 0x00, 0x34, 0x06, 0x00, 0x00, 0x00, 0x00, 0x2e, + 0x06, 0x00, 0x00, 0x36, 0x06, 0x00, 0x00, 0x3a, + 0x06, 0x00, 0x00, 0xba, 0x06, 0x00, 0x00, 0x6f, + 0x06, 0x00, 0x00, 0x28, 0x06, 0x2c, 0x06, 0x00, + 0x00, 0x47, 0x06, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x06, 0x37, 0x06, 0x4a, 0x06, 0x43, 0x06, 0x00, + 0x00, 0x45, 0x06, 0x46, 0x06, 0x33, 0x06, 0x39, + 0x06, 0x41, 0x06, 0x35, 0x06, 0x42, 0x06, 0x00, + 0x00, 0x34, 0x06, 0x2a, 0x06, 0x2b, 0x06, 0x2e, + 0x06, 0x00, 0x00, 0x36, 0x06, 0x38, 0x06, 0x3a, + 0x06, 0x6e, 0x06, 0x00, 0x00, 0xa1, 0x06, 0x27, + 0x06, 0x00, 0x01, 0x05, 0x08, 0x20, 0x21, 0x0b, + 0x06, 0x10, 0x23, 0x2a, 0x06, 0x1a, 0x1b, 0x1c, + 0x09, 0x0f, 0x17, 0x0b, 0x18, 0x07, 0x0a, 0x00, + 0x01, 0x04, 0x06, 0x0c, 0x0e, 0x10, 0x28, 0x06, + 0x2c, 0x06, 0x2f, 0x06, 0x00, 0x00, 0x48, 0x06, + 0x32, 0x06, 0x2d, 0x06, 0x37, 0x06, 0x4a, 0x06, + 0x2a, 0x06, 0x1a, 0x1b, 0x1c, 0x09, 0x0f, 0x17, + 0x0b, 0x18, 0x07, 0x0a, 0x00, 0x01, 0x04, 0x06, + 0x0c, 0x0e, 0x10, 0x30, 0x2e, 0x30, 0x00, 0x2c, + 0x00, 0x28, 0x00, 0x41, 0x00, 0x29, 0x00, 0x14, + 0x30, 0x53, 0x00, 0x15, 0x30, 0x43, 0x52, 0x43, + 0x44, 0x57, 0x5a, 0x41, 0x00, 0x48, 0x56, 0x4d, + 0x56, 0x53, 0x44, 0x53, 0x53, 0x50, 0x50, 0x56, + 0x57, 0x43, 0x4d, 0x43, 0x4d, 0x44, 0x4d, 0x52, + 0x44, 0x4a, 0x4b, 0x30, 0x30, 0x00, 0x68, 0x68, + 0x4b, 0x62, 0x57, 0x5b, 0xcc, 0x53, 0xc7, 0x30, + 0x8c, 0x4e, 0x1a, 0x59, 0xe3, 0x89, 0x29, 0x59, + 0xa4, 0x4e, 0x20, 0x66, 0x21, 0x71, 0x99, 0x65, + 0x4d, 0x52, 0x8c, 0x5f, 0x8d, 0x51, 0xb0, 0x65, + 0x1d, 0x52, 0x42, 0x7d, 0x1f, 0x75, 0xa9, 0x8c, + 0xf0, 0x58, 0x39, 0x54, 0x14, 0x6f, 0x95, 0x62, + 0x55, 0x63, 0x00, 0x4e, 0x09, 0x4e, 0x4a, 0x90, + 0xe6, 0x5d, 0x2d, 0x4e, 0xf3, 0x53, 0x07, 0x63, + 0x70, 0x8d, 0x53, 0x62, 0x81, 0x79, 0x7a, 0x7a, + 0x08, 0x54, 0x80, 0x6e, 0x09, 0x67, 0x08, 0x67, + 0x33, 0x75, 0x72, 0x52, 0xb6, 0x55, 0x4d, 0x91, + 0x14, 0x30, 0x15, 0x30, 0x2c, 0x67, 0x09, 0x4e, + 0x8c, 0x4e, 0x89, 0x5b, 0xb9, 0x70, 0x53, 0x62, + 0xd7, 0x76, 0xdd, 0x52, 0x57, 0x65, 0x97, 0x5f, + 0xef, 0x53, 0x30, 0x00, 0x38, 0x4e, 0x05, 0x00, + 0x09, 0x22, 0x01, 0x60, 0x4f, 0xae, 0x4f, 0xbb, + 0x4f, 0x02, 0x50, 0x7a, 0x50, 0x99, 0x50, 0xe7, + 0x50, 0xcf, 0x50, 0x9e, 0x34, 0x3a, 0x06, 0x4d, + 0x51, 0x54, 0x51, 0x64, 0x51, 0x77, 0x51, 0x1c, + 0x05, 0xb9, 0x34, 0x67, 0x51, 0x8d, 0x51, 0x4b, + 0x05, 0x97, 0x51, 0xa4, 0x51, 0xcc, 0x4e, 0xac, + 0x51, 0xb5, 0x51, 0xdf, 0x91, 0xf5, 0x51, 0x03, + 0x52, 0xdf, 0x34, 0x3b, 0x52, 0x46, 0x52, 0x72, + 0x52, 0x77, 0x52, 0x15, 0x35, 0x02, 0x00, 0x20, + 0x80, 0x80, 0x00, 0x08, 0x00, 0x00, 0xc7, 0x52, + 0x00, 0x02, 0x1d, 0x33, 0x3e, 0x3f, 0x50, 0x82, + 0x8a, 0x93, 0xac, 0xb6, 0xb8, 0xb8, 0xb8, 0x2c, + 0x0a, 0x70, 0x70, 0xca, 0x53, 0xdf, 0x53, 0x63, + 0x0b, 0xeb, 0x53, 0xf1, 0x53, 0x06, 0x54, 0x9e, + 0x54, 0x38, 0x54, 0x48, 0x54, 0x68, 0x54, 0xa2, + 0x54, 0xf6, 0x54, 0x10, 0x55, 0x53, 0x55, 0x63, + 0x55, 0x84, 0x55, 0x84, 0x55, 0x99, 0x55, 0xab, + 0x55, 0xb3, 0x55, 0xc2, 0x55, 0x16, 0x57, 0x06, + 0x56, 0x17, 0x57, 0x51, 0x56, 0x74, 0x56, 0x07, + 0x52, 0xee, 0x58, 0xce, 0x57, 0xf4, 0x57, 0x0d, + 0x58, 0x8b, 0x57, 0x32, 0x58, 0x31, 0x58, 0xac, + 0x58, 0xe4, 0x14, 0xf2, 0x58, 0xf7, 0x58, 0x06, + 0x59, 0x1a, 0x59, 0x22, 0x59, 0x62, 0x59, 0xa8, + 0x16, 0xea, 0x16, 0xec, 0x59, 0x1b, 0x5a, 0x27, + 0x5a, 0xd8, 0x59, 0x66, 0x5a, 0xee, 0x36, 0xfc, + 0x36, 0x08, 0x5b, 0x3e, 0x5b, 0x3e, 0x5b, 0xc8, + 0x19, 0xc3, 0x5b, 0xd8, 0x5b, 0xe7, 0x5b, 0xf3, + 0x5b, 0x18, 0x1b, 0xff, 0x5b, 0x06, 0x5c, 0x53, + 0x5f, 0x22, 0x5c, 0x81, 0x37, 0x60, 0x5c, 0x6e, + 0x5c, 0xc0, 0x5c, 0x8d, 0x5c, 0xe4, 0x1d, 0x43, + 0x5d, 0xe6, 0x1d, 0x6e, 0x5d, 0x6b, 0x5d, 0x7c, + 0x5d, 0xe1, 0x5d, 0xe2, 0x5d, 0x2f, 0x38, 0xfd, + 0x5d, 0x28, 0x5e, 0x3d, 0x5e, 0x69, 0x5e, 0x62, + 0x38, 0x83, 0x21, 0x7c, 0x38, 0xb0, 0x5e, 0xb3, + 0x5e, 0xb6, 0x5e, 0xca, 0x5e, 0x92, 0xa3, 0xfe, + 0x5e, 0x31, 0x23, 0x31, 0x23, 0x01, 0x82, 0x22, + 0x5f, 0x22, 0x5f, 0xc7, 0x38, 0xb8, 0x32, 0xda, + 0x61, 0x62, 0x5f, 0x6b, 0x5f, 0xe3, 0x38, 0x9a, + 0x5f, 0xcd, 0x5f, 0xd7, 0x5f, 0xf9, 0x5f, 0x81, + 0x60, 0x3a, 0x39, 0x1c, 0x39, 0x94, 0x60, 0xd4, + 0x26, 0xc7, 0x60, 0x02, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, + 0x00, 0x02, 0x08, 0x00, 0x80, 0x08, 0x00, 0x00, + 0x08, 0x80, 0x28, 0x80, 0x02, 0x00, 0x00, 0x02, + 0x48, 0x61, 0x00, 0x04, 0x06, 0x04, 0x32, 0x46, + 0x6a, 0x5c, 0x67, 0x96, 0xaa, 0xae, 0xc8, 0xd3, + 0x5d, 0x62, 0x00, 0x54, 0x77, 0xf3, 0x0c, 0x2b, + 0x3d, 0x63, 0xfc, 0x62, 0x68, 0x63, 0x83, 0x63, + 0xe4, 0x63, 0xf1, 0x2b, 0x22, 0x64, 0xc5, 0x63, + 0xa9, 0x63, 0x2e, 0x3a, 0x69, 0x64, 0x7e, 0x64, + 0x9d, 0x64, 0x77, 0x64, 0x6c, 0x3a, 0x4f, 0x65, + 0x6c, 0x65, 0x0a, 0x30, 0xe3, 0x65, 0xf8, 0x66, + 0x49, 0x66, 0x19, 0x3b, 0x91, 0x66, 0x08, 0x3b, + 0xe4, 0x3a, 0x92, 0x51, 0x95, 0x51, 0x00, 0x67, + 0x9c, 0x66, 0xad, 0x80, 0xd9, 0x43, 0x17, 0x67, + 0x1b, 0x67, 0x21, 0x67, 0x5e, 0x67, 0x53, 0x67, + 0xc3, 0x33, 0x49, 0x3b, 0xfa, 0x67, 0x85, 0x67, + 0x52, 0x68, 0x85, 0x68, 0x6d, 0x34, 0x8e, 0x68, + 0x1f, 0x68, 0x14, 0x69, 0x9d, 0x3b, 0x42, 0x69, + 0xa3, 0x69, 0xea, 0x69, 0xa8, 0x6a, 0xa3, 0x36, + 0xdb, 0x6a, 0x18, 0x3c, 0x21, 0x6b, 0xa7, 0x38, + 0x54, 0x6b, 0x4e, 0x3c, 0x72, 0x6b, 0x9f, 0x6b, + 0xba, 0x6b, 0xbb, 0x6b, 0x8d, 0x3a, 0x0b, 0x1d, + 0xfa, 0x3a, 0x4e, 0x6c, 0xbc, 0x3c, 0xbf, 0x6c, + 0xcd, 0x6c, 0x67, 0x6c, 0x16, 0x6d, 0x3e, 0x6d, + 0x77, 0x6d, 0x41, 0x6d, 0x69, 0x6d, 0x78, 0x6d, + 0x85, 0x6d, 0x1e, 0x3d, 0x34, 0x6d, 0x2f, 0x6e, + 0x6e, 0x6e, 0x33, 0x3d, 0xcb, 0x6e, 0xc7, 0x6e, + 0xd1, 0x3e, 0xf9, 0x6d, 0x6e, 0x6f, 0x5e, 0x3f, + 0x8e, 0x3f, 0xc6, 0x6f, 0x39, 0x70, 0x1e, 0x70, + 0x1b, 0x70, 0x96, 0x3d, 0x4a, 0x70, 0x7d, 0x70, + 0x77, 0x70, 0xad, 0x70, 0x25, 0x05, 0x45, 0x71, + 0x63, 0x42, 0x9c, 0x71, 0xab, 0x43, 0x28, 0x72, + 0x35, 0x72, 0x50, 0x72, 0x08, 0x46, 0x80, 0x72, + 0x95, 0x72, 0x35, 0x47, 0x02, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, + 0x00, 0x02, 0x02, 0x80, 0x8a, 0x00, 0x00, 0x20, + 0x00, 0x08, 0x0a, 0x00, 0x80, 0x88, 0x80, 0x20, + 0x14, 0x48, 0x7a, 0x73, 0x8b, 0x73, 0xac, 0x3e, + 0xa5, 0x73, 0xb8, 0x3e, 0xb8, 0x3e, 0x47, 0x74, + 0x5c, 0x74, 0x71, 0x74, 0x85, 0x74, 0xca, 0x74, + 0x1b, 0x3f, 0x24, 0x75, 0x36, 0x4c, 0x3e, 0x75, + 0x92, 0x4c, 0x70, 0x75, 0x9f, 0x21, 0x10, 0x76, + 0xa1, 0x4f, 0xb8, 0x4f, 0x44, 0x50, 0xfc, 0x3f, + 0x08, 0x40, 0xf4, 0x76, 0xf3, 0x50, 0xf2, 0x50, + 0x19, 0x51, 0x33, 0x51, 0x1e, 0x77, 0x1f, 0x77, + 0x1f, 0x77, 0x4a, 0x77, 0x39, 0x40, 0x8b, 0x77, + 0x46, 0x40, 0x96, 0x40, 0x1d, 0x54, 0x4e, 0x78, + 0x8c, 0x78, 0xcc, 0x78, 0xe3, 0x40, 0x26, 0x56, + 0x56, 0x79, 0x9a, 0x56, 0xc5, 0x56, 0x8f, 0x79, + 0xeb, 0x79, 0x2f, 0x41, 0x40, 0x7a, 0x4a, 0x7a, + 0x4f, 0x7a, 0x7c, 0x59, 0xa7, 0x5a, 0xa7, 0x5a, + 0xee, 0x7a, 0x02, 0x42, 0xab, 0x5b, 0xc6, 0x7b, + 0xc9, 0x7b, 0x27, 0x42, 0x80, 0x5c, 0xd2, 0x7c, + 0xa0, 0x42, 0xe8, 0x7c, 0xe3, 0x7c, 0x00, 0x7d, + 0x86, 0x5f, 0x63, 0x7d, 0x01, 0x43, 0xc7, 0x7d, + 0x02, 0x7e, 0x45, 0x7e, 0x34, 0x43, 0x28, 0x62, + 0x47, 0x62, 0x59, 0x43, 0xd9, 0x62, 0x7a, 0x7f, + 0x3e, 0x63, 0x95, 0x7f, 0xfa, 0x7f, 0x05, 0x80, + 0xda, 0x64, 0x23, 0x65, 0x60, 0x80, 0xa8, 0x65, + 0x70, 0x80, 0x5f, 0x33, 0xd5, 0x43, 0xb2, 0x80, + 0x03, 0x81, 0x0b, 0x44, 0x3e, 0x81, 0xb5, 0x5a, + 0xa7, 0x67, 0xb5, 0x67, 0x93, 0x33, 0x9c, 0x33, + 0x01, 0x82, 0x04, 0x82, 0x9e, 0x8f, 0x6b, 0x44, + 0x91, 0x82, 0x8b, 0x82, 0x9d, 0x82, 0xb3, 0x52, + 0xb1, 0x82, 0xb3, 0x82, 0xbd, 0x82, 0xe6, 0x82, + 0x3c, 0x6b, 0xe5, 0x82, 0x1d, 0x83, 0x63, 0x83, + 0xad, 0x83, 0x23, 0x83, 0xbd, 0x83, 0xe7, 0x83, + 0x57, 0x84, 0x53, 0x83, 0xca, 0x83, 0xcc, 0x83, + 0xdc, 0x83, 0x36, 0x6c, 0x6b, 0x6d, 0x02, 0x00, + 0x00, 0x20, 0x22, 0x2a, 0xa0, 0x0a, 0x00, 0x20, + 0x80, 0x28, 0x00, 0xa8, 0x20, 0x20, 0x00, 0x02, + 0x80, 0x22, 0x02, 0x8a, 0x08, 0x00, 0xaa, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x28, 0xd5, 0x6c, + 0x2b, 0x45, 0xf1, 0x84, 0xf3, 0x84, 0x16, 0x85, + 0xca, 0x73, 0x64, 0x85, 0x2c, 0x6f, 0x5d, 0x45, + 0x61, 0x45, 0xb1, 0x6f, 0xd2, 0x70, 0x6b, 0x45, + 0x50, 0x86, 0x5c, 0x86, 0x67, 0x86, 0x69, 0x86, + 0xa9, 0x86, 0x88, 0x86, 0x0e, 0x87, 0xe2, 0x86, + 0x79, 0x87, 0x28, 0x87, 0x6b, 0x87, 0x86, 0x87, + 0xd7, 0x45, 0xe1, 0x87, 0x01, 0x88, 0xf9, 0x45, + 0x60, 0x88, 0x63, 0x88, 0x67, 0x76, 0xd7, 0x88, + 0xde, 0x88, 0x35, 0x46, 0xfa, 0x88, 0xbb, 0x34, + 0xae, 0x78, 0x66, 0x79, 0xbe, 0x46, 0xc7, 0x46, + 0xa0, 0x8a, 0xed, 0x8a, 0x8a, 0x8b, 0x55, 0x8c, + 0xa8, 0x7c, 0xab, 0x8c, 0xc1, 0x8c, 0x1b, 0x8d, + 0x77, 0x8d, 0x2f, 0x7f, 0x04, 0x08, 0xcb, 0x8d, + 0xbc, 0x8d, 0xf0, 0x8d, 0xde, 0x08, 0xd4, 0x8e, + 0x38, 0x8f, 0xd2, 0x85, 0xed, 0x85, 0x94, 0x90, + 0xf1, 0x90, 0x11, 0x91, 0x2e, 0x87, 0x1b, 0x91, + 0x38, 0x92, 0xd7, 0x92, 0xd8, 0x92, 0x7c, 0x92, + 0xf9, 0x93, 0x15, 0x94, 0xfa, 0x8b, 0x8b, 0x95, + 0x95, 0x49, 0xb7, 0x95, 0x77, 0x8d, 0xe6, 0x49, + 0xc3, 0x96, 0xb2, 0x5d, 0x23, 0x97, 0x45, 0x91, + 0x1a, 0x92, 0x6e, 0x4a, 0x76, 0x4a, 0xe0, 0x97, + 0x0a, 0x94, 0xb2, 0x4a, 0x96, 0x94, 0x0b, 0x98, + 0x0b, 0x98, 0x29, 0x98, 0xb6, 0x95, 0xe2, 0x98, + 0x33, 0x4b, 0x29, 0x99, 0xa7, 0x99, 0xc2, 0x99, + 0xfe, 0x99, 0xce, 0x4b, 0x30, 0x9b, 0x12, 0x9b, + 0x40, 0x9c, 0xfd, 0x9c, 0xce, 0x4c, 0xed, 0x4c, + 0x67, 0x9d, 0xce, 0xa0, 0xf8, 0x4c, 0x05, 0xa1, + 0x0e, 0xa2, 0x91, 0xa2, 0xbb, 0x9e, 0x56, 0x4d, + 0xf9, 0x9e, 0xfe, 0x9e, 0x05, 0x9f, 0x0f, 0x9f, + 0x16, 0x9f, 0x3b, 0x9f, 0x00, 0xa6, 0x02, 0x88, + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x28, + 0x00, 0x08, 0xa0, 0x80, 0xa0, 0x80, 0x00, 0x80, + 0x80, 0x00, 0x0a, 0x88, 0x80, 0x00, 0x80, 0x00, + 0x20, 0x2a, 0x00, 0x80, +}; + +static const uint16_t unicode_comp_table[945] = { + 0x4a01, 0x49c0, 0x4a02, 0x0280, 0x0281, 0x0282, 0x0283, 0x02c0, + 0x02c2, 0x0a00, 0x0284, 0x2442, 0x0285, 0x07c0, 0x0980, 0x0982, + 0x2440, 0x2280, 0x02c4, 0x2282, 0x2284, 0x2286, 0x02c6, 0x02c8, + 0x02ca, 0x02cc, 0x0287, 0x228a, 0x02ce, 0x228c, 0x2290, 0x2292, + 0x228e, 0x0288, 0x0289, 0x028a, 0x2482, 0x0300, 0x0302, 0x0304, + 0x028b, 0x2480, 0x0308, 0x0984, 0x0986, 0x2458, 0x0a02, 0x0306, + 0x2298, 0x229a, 0x229e, 0x0900, 0x030a, 0x22a0, 0x030c, 0x030e, + 0x0840, 0x0310, 0x0312, 0x22a2, 0x22a6, 0x09c0, 0x22a4, 0x22a8, + 0x22aa, 0x028c, 0x028d, 0x028e, 0x0340, 0x0342, 0x0344, 0x0380, + 0x028f, 0x248e, 0x07c2, 0x0988, 0x098a, 0x2490, 0x0346, 0x22ac, + 0x0400, 0x22b0, 0x0842, 0x22b2, 0x0402, 0x22b4, 0x0440, 0x0444, + 0x22b6, 0x0442, 0x22c2, 0x22c0, 0x22c4, 0x22c6, 0x22c8, 0x0940, + 0x04c0, 0x0291, 0x22ca, 0x04c4, 0x22cc, 0x04c2, 0x22d0, 0x22ce, + 0x0292, 0x0293, 0x0294, 0x0295, 0x0540, 0x0542, 0x0a08, 0x0296, + 0x2494, 0x0544, 0x07c4, 0x098c, 0x098e, 0x06c0, 0x2492, 0x0844, + 0x2308, 0x230a, 0x0580, 0x230c, 0x0584, 0x0990, 0x0992, 0x230e, + 0x0582, 0x2312, 0x0586, 0x0588, 0x2314, 0x058c, 0x2316, 0x0998, + 0x058a, 0x231e, 0x0590, 0x2320, 0x099a, 0x058e, 0x2324, 0x2322, + 0x0299, 0x029a, 0x029b, 0x05c0, 0x05c2, 0x05c4, 0x029c, 0x24ac, + 0x05c6, 0x05c8, 0x07c6, 0x0994, 0x0996, 0x0700, 0x24aa, 0x2326, + 0x05ca, 0x232a, 0x2328, 0x2340, 0x2342, 0x2344, 0x2346, 0x05cc, + 0x234a, 0x2348, 0x234c, 0x234e, 0x2350, 0x24b8, 0x029d, 0x05ce, + 0x24be, 0x0a0c, 0x2352, 0x0600, 0x24bc, 0x24ba, 0x0640, 0x2354, + 0x0642, 0x0644, 0x2356, 0x2358, 0x02a0, 0x02a1, 0x02a2, 0x02a3, + 0x02c1, 0x02c3, 0x0a01, 0x02a4, 0x2443, 0x02a5, 0x07c1, 0x0981, + 0x0983, 0x2441, 0x2281, 0x02c5, 0x2283, 0x2285, 0x2287, 0x02c7, + 0x02c9, 0x02cb, 0x02cd, 0x02a7, 0x228b, 0x02cf, 0x228d, 0x2291, + 0x2293, 0x228f, 0x02a8, 0x02a9, 0x02aa, 0x2483, 0x0301, 0x0303, + 0x0305, 0x02ab, 0x2481, 0x0309, 0x0985, 0x0987, 0x2459, 0x0a03, + 0x0307, 0x2299, 0x229b, 0x229f, 0x0901, 0x030b, 0x22a1, 0x030d, + 0x030f, 0x0841, 0x0311, 0x0313, 0x22a3, 0x22a7, 0x09c1, 0x22a5, + 0x22a9, 0x22ab, 0x2380, 0x02ac, 0x02ad, 0x02ae, 0x0341, 0x0343, + 0x0345, 0x02af, 0x248f, 0x07c3, 0x0989, 0x098b, 0x2491, 0x0347, + 0x22ad, 0x0401, 0x0884, 0x22b1, 0x0843, 0x22b3, 0x0403, 0x22b5, + 0x0441, 0x0445, 0x22b7, 0x0443, 0x22c3, 0x22c1, 0x22c5, 0x22c7, + 0x22c9, 0x0941, 0x04c1, 0x02b1, 0x22cb, 0x04c5, 0x22cd, 0x04c3, + 0x22d1, 0x22cf, 0x02b2, 0x02b3, 0x02b4, 0x02b5, 0x0541, 0x0543, + 0x0a09, 0x02b6, 0x2495, 0x0545, 0x07c5, 0x098d, 0x098f, 0x06c1, + 0x2493, 0x0845, 0x2309, 0x230b, 0x0581, 0x230d, 0x0585, 0x0991, + 0x0993, 0x230f, 0x0583, 0x2313, 0x0587, 0x0589, 0x2315, 0x058d, + 0x2317, 0x0999, 0x058b, 0x231f, 0x2381, 0x0591, 0x2321, 0x099b, + 0x058f, 0x2325, 0x2323, 0x02b9, 0x02ba, 0x02bb, 0x05c1, 0x05c3, + 0x05c5, 0x02bc, 0x24ad, 0x05c7, 0x05c9, 0x07c7, 0x0995, 0x0997, + 0x0701, 0x24ab, 0x2327, 0x05cb, 0x232b, 0x2329, 0x2341, 0x2343, + 0x2345, 0x2347, 0x05cd, 0x234b, 0x2349, 0x2382, 0x234d, 0x234f, + 0x2351, 0x24b9, 0x02bd, 0x05cf, 0x24bf, 0x0a0d, 0x2353, 0x02bf, + 0x24bd, 0x2383, 0x24bb, 0x0641, 0x2355, 0x0643, 0x0645, 0x2357, + 0x2359, 0x3101, 0x0c80, 0x2e00, 0x2446, 0x2444, 0x244a, 0x2448, + 0x0800, 0x0942, 0x0944, 0x0804, 0x2288, 0x2486, 0x2484, 0x248a, + 0x2488, 0x22ae, 0x2498, 0x2496, 0x249c, 0x249a, 0x2300, 0x0a06, + 0x2302, 0x0a04, 0x0946, 0x07ce, 0x07ca, 0x07c8, 0x07cc, 0x2447, + 0x2445, 0x244b, 0x2449, 0x0801, 0x0943, 0x0945, 0x0805, 0x2289, + 0x2487, 0x2485, 0x248b, 0x2489, 0x22af, 0x2499, 0x2497, 0x249d, + 0x249b, 0x2301, 0x0a07, 0x2303, 0x0a05, 0x0947, 0x07cf, 0x07cb, + 0x07c9, 0x07cd, 0x2450, 0x244e, 0x2454, 0x2452, 0x2451, 0x244f, + 0x2455, 0x2453, 0x2294, 0x2296, 0x2295, 0x2297, 0x2304, 0x2306, + 0x2305, 0x2307, 0x2318, 0x2319, 0x231a, 0x231b, 0x232c, 0x232d, + 0x232e, 0x232f, 0x2400, 0x24a2, 0x24a0, 0x24a6, 0x24a4, 0x24a8, + 0x24a3, 0x24a1, 0x24a7, 0x24a5, 0x24a9, 0x24b0, 0x24ae, 0x24b4, + 0x24b2, 0x24b6, 0x24b1, 0x24af, 0x24b5, 0x24b3, 0x24b7, 0x0882, + 0x0880, 0x0881, 0x0802, 0x0803, 0x229c, 0x229d, 0x0a0a, 0x0a0b, + 0x0883, 0x0b40, 0x2c8a, 0x0c81, 0x2c89, 0x2c88, 0x2540, 0x2541, + 0x2d00, 0x2e07, 0x0d00, 0x2640, 0x2641, 0x2e80, 0x0d01, 0x26c8, + 0x26c9, 0x2f00, 0x2f84, 0x0d02, 0x2f83, 0x2f82, 0x0d40, 0x26d8, + 0x26d9, 0x3186, 0x0d04, 0x2740, 0x2741, 0x3100, 0x3086, 0x0d06, + 0x3085, 0x3084, 0x0d41, 0x2840, 0x3200, 0x0d07, 0x284f, 0x2850, + 0x3280, 0x2c84, 0x2e03, 0x2857, 0x0d42, 0x2c81, 0x2c80, 0x24c0, + 0x24c1, 0x2c86, 0x2c83, 0x28c0, 0x0d43, 0x25c0, 0x25c1, 0x2940, + 0x0d44, 0x26c0, 0x26c1, 0x2e05, 0x2e02, 0x29c0, 0x0d45, 0x2f05, + 0x2f04, 0x0d80, 0x26d0, 0x26d1, 0x2f80, 0x2a40, 0x0d82, 0x26e0, + 0x26e1, 0x3080, 0x3081, 0x2ac0, 0x0d83, 0x3004, 0x3003, 0x0d81, + 0x27c0, 0x27c1, 0x3082, 0x2b40, 0x0d84, 0x2847, 0x2848, 0x3184, + 0x3181, 0x2f06, 0x0d08, 0x2f81, 0x3005, 0x0d46, 0x3083, 0x3182, + 0x0e00, 0x0e01, 0x0f40, 0x1180, 0x1182, 0x0f03, 0x0f00, 0x11c0, + 0x0f01, 0x1140, 0x1202, 0x1204, 0x0f81, 0x1240, 0x0fc0, 0x1242, + 0x0f80, 0x1244, 0x1284, 0x0f82, 0x1286, 0x1288, 0x128a, 0x12c0, + 0x1282, 0x1181, 0x1183, 0x1043, 0x1040, 0x11c1, 0x1041, 0x1141, + 0x1203, 0x1205, 0x10c1, 0x1241, 0x1000, 0x1243, 0x10c0, 0x1245, + 0x1285, 0x10c2, 0x1287, 0x1289, 0x128b, 0x12c1, 0x1283, 0x1080, + 0x1100, 0x1101, 0x1200, 0x1201, 0x1280, 0x1281, 0x1340, 0x1341, + 0x1343, 0x1342, 0x1344, 0x13c2, 0x1400, 0x13c0, 0x1440, 0x1480, + 0x14c0, 0x1540, 0x1541, 0x1740, 0x1700, 0x1741, 0x17c0, 0x1800, + 0x1802, 0x1801, 0x1840, 0x1880, 0x1900, 0x18c0, 0x18c1, 0x1901, + 0x1940, 0x1942, 0x1941, 0x1980, 0x19c0, 0x19c2, 0x19c1, 0x1c80, + 0x1cc0, 0x1dc0, 0x1f80, 0x2000, 0x2002, 0x2004, 0x2006, 0x2008, + 0x2040, 0x2080, 0x2082, 0x20c0, 0x20c1, 0x2100, 0x22b8, 0x22b9, + 0x2310, 0x2311, 0x231c, 0x231d, 0x244c, 0x2456, 0x244d, 0x2457, + 0x248c, 0x248d, 0x249e, 0x249f, 0x2500, 0x2502, 0x2504, 0x2bc0, + 0x2501, 0x2503, 0x2505, 0x2bc1, 0x2bc2, 0x2bc3, 0x2bc4, 0x2bc5, + 0x2bc6, 0x2bc7, 0x2580, 0x2582, 0x2584, 0x2bc8, 0x2581, 0x2583, + 0x2585, 0x2bc9, 0x2bca, 0x2bcb, 0x2bcc, 0x2bcd, 0x2bce, 0x2bcf, + 0x2600, 0x2602, 0x2601, 0x2603, 0x2680, 0x2682, 0x2681, 0x2683, + 0x26c2, 0x26c4, 0x26c6, 0x2c00, 0x26c3, 0x26c5, 0x26c7, 0x2c01, + 0x2c02, 0x2c03, 0x2c04, 0x2c05, 0x2c06, 0x2c07, 0x26ca, 0x26cc, + 0x26ce, 0x2c08, 0x26cb, 0x26cd, 0x26cf, 0x2c09, 0x2c0a, 0x2c0b, + 0x2c0c, 0x2c0d, 0x2c0e, 0x2c0f, 0x26d2, 0x26d4, 0x26d6, 0x26d3, + 0x26d5, 0x26d7, 0x26da, 0x26dc, 0x26de, 0x26db, 0x26dd, 0x26df, + 0x2700, 0x2702, 0x2701, 0x2703, 0x2780, 0x2782, 0x2781, 0x2783, + 0x2800, 0x2802, 0x2804, 0x2801, 0x2803, 0x2805, 0x2842, 0x2844, + 0x2846, 0x2849, 0x284b, 0x284d, 0x2c40, 0x284a, 0x284c, 0x284e, + 0x2c41, 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47, 0x2851, + 0x2853, 0x2855, 0x2c48, 0x2852, 0x2854, 0x2856, 0x2c49, 0x2c4a, + 0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f, 0x2c82, 0x2e01, 0x3180, + 0x2c87, 0x2f01, 0x2f02, 0x2f03, 0x2e06, 0x3185, 0x3000, 0x3001, + 0x3002, 0x4640, 0x4641, 0x4680, 0x46c0, 0x46c2, 0x46c1, 0x4700, + 0x4740, 0x4780, 0x47c0, 0x47c2, 0x4900, 0x4940, 0x4980, 0x4982, + 0x4a00, 0x49c2, 0x4a03, 0x4a04, 0x4a40, 0x4a41, 0x4a80, 0x4a81, + 0x4ac0, 0x4ac1, 0x4bc0, 0x4bc1, 0x4b00, 0x4b01, 0x4b40, 0x4b41, + 0x4bc2, 0x4bc3, 0x4b80, 0x4b81, 0x4b82, 0x4b83, 0x4c00, 0x4c01, + 0x4c02, 0x4c03, 0x5600, 0x5440, 0x5442, 0x5444, 0x5446, 0x5448, + 0x544a, 0x544c, 0x544e, 0x5450, 0x5452, 0x5454, 0x5456, 0x5480, + 0x5482, 0x5484, 0x54c0, 0x54c1, 0x5500, 0x5501, 0x5540, 0x5541, + 0x5580, 0x5581, 0x55c0, 0x55c1, 0x5680, 0x58c0, 0x5700, 0x5702, + 0x5704, 0x5706, 0x5708, 0x570a, 0x570c, 0x570e, 0x5710, 0x5712, + 0x5714, 0x5716, 0x5740, 0x5742, 0x5744, 0x5780, 0x5781, 0x57c0, + 0x57c1, 0x5800, 0x5801, 0x5840, 0x5841, 0x5880, 0x5881, 0x5900, + 0x5901, 0x5902, 0x5903, 0x5940, 0x8f40, 0x8f42, 0x8f80, 0x8fc0, + 0x8fc1, 0x9000, 0x9001, 0x9041, 0x9040, 0x9043, 0x9080, 0x9081, + 0x90c0, +}; + +typedef enum { + UNICODE_GC_Cn, + UNICODE_GC_Lu, + UNICODE_GC_Ll, + UNICODE_GC_Lt, + UNICODE_GC_Lm, + UNICODE_GC_Lo, + UNICODE_GC_Mn, + UNICODE_GC_Mc, + UNICODE_GC_Me, + UNICODE_GC_Nd, + UNICODE_GC_Nl, + UNICODE_GC_No, + UNICODE_GC_Sm, + UNICODE_GC_Sc, + UNICODE_GC_Sk, + UNICODE_GC_So, + UNICODE_GC_Pc, + UNICODE_GC_Pd, + UNICODE_GC_Ps, + UNICODE_GC_Pe, + UNICODE_GC_Pi, + UNICODE_GC_Pf, + UNICODE_GC_Po, + UNICODE_GC_Zs, + UNICODE_GC_Zl, + UNICODE_GC_Zp, + UNICODE_GC_Cc, + UNICODE_GC_Cf, + UNICODE_GC_Cs, + UNICODE_GC_Co, + UNICODE_GC_LC, + UNICODE_GC_L, + UNICODE_GC_M, + UNICODE_GC_N, + UNICODE_GC_S, + UNICODE_GC_P, + UNICODE_GC_Z, + UNICODE_GC_C, + UNICODE_GC_COUNT, +} UnicodeGCEnum; + +static const char unicode_gc_name_table[] = + "Cn,Unassigned" "\0" + "Lu,Uppercase_Letter" "\0" + "Ll,Lowercase_Letter" "\0" + "Lt,Titlecase_Letter" "\0" + "Lm,Modifier_Letter" "\0" + "Lo,Other_Letter" "\0" + "Mn,Nonspacing_Mark" "\0" + "Mc,Spacing_Mark" "\0" + "Me,Enclosing_Mark" "\0" + "Nd,Decimal_Number,digit" "\0" + "Nl,Letter_Number" "\0" + "No,Other_Number" "\0" + "Sm,Math_Symbol" "\0" + "Sc,Currency_Symbol" "\0" + "Sk,Modifier_Symbol" "\0" + "So,Other_Symbol" "\0" + "Pc,Connector_Punctuation" "\0" + "Pd,Dash_Punctuation" "\0" + "Ps,Open_Punctuation" "\0" + "Pe,Close_Punctuation" "\0" + "Pi,Initial_Punctuation" "\0" + "Pf,Final_Punctuation" "\0" + "Po,Other_Punctuation" "\0" + "Zs,Space_Separator" "\0" + "Zl,Line_Separator" "\0" + "Zp,Paragraph_Separator" "\0" + "Cc,Control,cntrl" "\0" + "Cf,Format" "\0" + "Cs,Surrogate" "\0" + "Co,Private_Use" "\0" + "LC,Cased_Letter" "\0" + "L,Letter" "\0" + "M,Mark,Combining_Mark" "\0" + "N,Number" "\0" + "S,Symbol" "\0" + "P,Punctuation,punct" "\0" + "Z,Separator" "\0" + "C,Other" "\0" +; + +static const uint8_t unicode_gc_table[3897] = { + 0xfa, 0x18, 0x17, 0x56, 0x0d, 0x56, 0x12, 0x13, + 0x16, 0x0c, 0x16, 0x11, 0x36, 0xe9, 0x02, 0x36, + 0x4c, 0x36, 0xe1, 0x12, 0x12, 0x16, 0x13, 0x0e, + 0x10, 0x0e, 0xe2, 0x12, 0x12, 0x0c, 0x13, 0x0c, + 0xfa, 0x19, 0x17, 0x16, 0x6d, 0x0f, 0x16, 0x0e, + 0x0f, 0x05, 0x14, 0x0c, 0x1b, 0x0f, 0x0e, 0x0f, + 0x0c, 0x2b, 0x0e, 0x02, 0x36, 0x0e, 0x0b, 0x05, + 0x15, 0x4b, 0x16, 0xe1, 0x0f, 0x0c, 0xc1, 0xe2, + 0x10, 0x0c, 0xe2, 0x00, 0xff, 0x30, 0x02, 0xff, + 0x08, 0x02, 0xff, 0x27, 0xbf, 0x22, 0x21, 0x02, + 0x5f, 0x5f, 0x21, 0x22, 0x61, 0x02, 0x21, 0x02, + 0x41, 0x42, 0x21, 0x02, 0x21, 0x02, 0x9f, 0x7f, + 0x02, 0x5f, 0x5f, 0x21, 0x02, 0x5f, 0x3f, 0x02, + 0x05, 0x3f, 0x22, 0x65, 0x01, 0x03, 0x02, 0x01, + 0x03, 0x02, 0x01, 0x03, 0x02, 0xff, 0x08, 0x02, + 0xff, 0x0a, 0x02, 0x01, 0x03, 0x02, 0x5f, 0x21, + 0x02, 0xff, 0x32, 0xa2, 0x21, 0x02, 0x21, 0x22, + 0x5f, 0x41, 0x02, 0xff, 0x00, 0xe2, 0x3c, 0x05, + 0xe2, 0x13, 0xe4, 0x0a, 0x6e, 0xe4, 0x04, 0xee, + 0x06, 0x84, 0xce, 0x04, 0x0e, 0x04, 0xee, 0x09, + 0xe6, 0x68, 0x7f, 0x04, 0x0e, 0x3f, 0x20, 0x04, + 0x42, 0x16, 0x01, 0x60, 0x2e, 0x01, 0x16, 0x41, + 0x00, 0x01, 0x00, 0x21, 0x02, 0xe1, 0x09, 0x00, + 0xe1, 0x01, 0xe2, 0x1b, 0x3f, 0x02, 0x41, 0x42, + 0xff, 0x10, 0x62, 0x3f, 0x0c, 0x5f, 0x3f, 0x02, + 0xe1, 0x2b, 0xe2, 0x28, 0xff, 0x1a, 0x0f, 0x86, + 0x28, 0xff, 0x2f, 0xff, 0x06, 0x02, 0xff, 0x58, + 0x00, 0xe1, 0x1e, 0x20, 0x04, 0xb6, 0xe2, 0x21, + 0x16, 0x11, 0x20, 0x2f, 0x0d, 0x00, 0xe6, 0x25, + 0x11, 0x06, 0x16, 0x26, 0x16, 0x26, 0x16, 0x06, + 0xe0, 0x00, 0xe5, 0x13, 0x60, 0x65, 0x36, 0xe0, + 0x03, 0xbb, 0x4c, 0x36, 0x0d, 0x36, 0x2f, 0xe6, + 0x03, 0x16, 0x1b, 0x56, 0xe5, 0x18, 0x04, 0xe5, + 0x02, 0xe6, 0x0d, 0xe9, 0x02, 0x76, 0x25, 0x06, + 0xe5, 0x5b, 0x16, 0x05, 0xc6, 0x1b, 0x0f, 0xa6, + 0x24, 0x26, 0x0f, 0x66, 0x25, 0xe9, 0x02, 0x45, + 0x2f, 0x05, 0xf6, 0x06, 0x00, 0x1b, 0x05, 0x06, + 0xe5, 0x16, 0xe6, 0x13, 0x20, 0xe5, 0x51, 0xe6, + 0x03, 0x05, 0xe0, 0x06, 0xe9, 0x02, 0xe5, 0x19, + 0xe6, 0x01, 0x24, 0x0f, 0x56, 0x04, 0x20, 0x06, + 0x2d, 0xe5, 0x0e, 0x66, 0x04, 0xe6, 0x01, 0x04, + 0x46, 0x04, 0x86, 0x20, 0xf6, 0x07, 0x00, 0xe5, + 0x11, 0x46, 0x20, 0x16, 0x00, 0xe5, 0x03, 0x80, + 0xe5, 0x10, 0x0e, 0xa5, 0x00, 0x3b, 0xa0, 0xe6, + 0x00, 0xe5, 0x21, 0x04, 0xe6, 0x10, 0x1b, 0xe6, + 0x18, 0x07, 0xe5, 0x2e, 0x06, 0x07, 0x06, 0x05, + 0x47, 0xe6, 0x00, 0x67, 0x06, 0x27, 0x05, 0xc6, + 0xe5, 0x02, 0x26, 0x36, 0xe9, 0x02, 0x16, 0x04, + 0xe5, 0x07, 0x06, 0x27, 0x00, 0xe5, 0x00, 0x20, + 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x05, + 0x40, 0x65, 0x20, 0x06, 0x05, 0x47, 0x66, 0x20, + 0x27, 0x20, 0x27, 0x06, 0x05, 0xe0, 0x00, 0x07, + 0x60, 0x25, 0x00, 0x45, 0x26, 0x20, 0xe9, 0x02, + 0x25, 0x2d, 0xab, 0x0f, 0x0d, 0x05, 0x16, 0x06, + 0x20, 0x26, 0x07, 0x00, 0xa5, 0x60, 0x25, 0x20, + 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, 0x25, + 0x00, 0x25, 0x20, 0x06, 0x00, 0x47, 0x26, 0x60, + 0x26, 0x20, 0x46, 0x40, 0x06, 0xc0, 0x65, 0x00, + 0x05, 0xc0, 0xe9, 0x02, 0x26, 0x45, 0x06, 0x16, + 0xe0, 0x02, 0x26, 0x07, 0x00, 0xe5, 0x01, 0x00, + 0x45, 0x00, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, + 0x00, 0x85, 0x20, 0x06, 0x05, 0x47, 0x86, 0x00, + 0x26, 0x07, 0x00, 0x27, 0x06, 0x20, 0x05, 0xe0, + 0x07, 0x25, 0x26, 0x20, 0xe9, 0x02, 0x16, 0x0d, + 0xc0, 0x05, 0xa6, 0x00, 0x06, 0x27, 0x00, 0xe5, + 0x00, 0x20, 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, + 0x00, 0x25, 0x00, 0x85, 0x20, 0x06, 0x05, 0x07, + 0x06, 0x07, 0x66, 0x20, 0x27, 0x20, 0x27, 0x06, + 0xc0, 0x26, 0x07, 0x60, 0x25, 0x00, 0x45, 0x26, + 0x20, 0xe9, 0x02, 0x0f, 0x05, 0xab, 0xe0, 0x02, + 0x06, 0x05, 0x00, 0xa5, 0x40, 0x45, 0x00, 0x65, + 0x40, 0x25, 0x00, 0x05, 0x00, 0x25, 0x40, 0x25, + 0x40, 0x45, 0x40, 0xe5, 0x04, 0x60, 0x27, 0x06, + 0x27, 0x40, 0x47, 0x00, 0x47, 0x06, 0x20, 0x05, + 0xa0, 0x07, 0xe0, 0x06, 0xe9, 0x02, 0x4b, 0xaf, + 0x0d, 0x0f, 0x80, 0x06, 0x47, 0x06, 0xe5, 0x00, + 0x00, 0x45, 0x00, 0xe5, 0x0f, 0x00, 0xe5, 0x08, + 0x20, 0x06, 0x05, 0x46, 0x67, 0x00, 0x46, 0x00, + 0x66, 0xc0, 0x26, 0x00, 0x45, 0x20, 0x05, 0x20, + 0x25, 0x26, 0x20, 0xe9, 0x02, 0xc0, 0x16, 0xcb, + 0x0f, 0x05, 0x06, 0x27, 0x16, 0xe5, 0x00, 0x00, + 0x45, 0x00, 0xe5, 0x0f, 0x00, 0xe5, 0x02, 0x00, + 0x85, 0x20, 0x06, 0x05, 0x07, 0x06, 0x87, 0x00, + 0x06, 0x27, 0x00, 0x27, 0x26, 0xc0, 0x27, 0xa0, + 0x25, 0x00, 0x25, 0x26, 0x20, 0xe9, 0x02, 0x00, + 0x25, 0xe0, 0x05, 0x26, 0x27, 0xe5, 0x01, 0x00, + 0x45, 0x00, 0xe5, 0x21, 0x26, 0x05, 0x47, 0x66, + 0x00, 0x47, 0x00, 0x47, 0x06, 0x05, 0x0f, 0x60, + 0x45, 0x07, 0xcb, 0x45, 0x26, 0x20, 0xe9, 0x02, + 0xeb, 0x01, 0x0f, 0xa5, 0x00, 0x06, 0x27, 0x00, + 0xe5, 0x0a, 0x40, 0xe5, 0x10, 0x00, 0xe5, 0x01, + 0x00, 0x05, 0x20, 0xc5, 0x40, 0x06, 0x60, 0x47, + 0x46, 0x00, 0x06, 0x00, 0xe7, 0x00, 0xa0, 0xe9, + 0x02, 0x20, 0x27, 0x16, 0xe0, 0x04, 0xe5, 0x28, + 0x06, 0x25, 0xc6, 0x60, 0x0d, 0xa5, 0x04, 0xe6, + 0x00, 0x16, 0xe9, 0x02, 0x36, 0xe0, 0x1d, 0x25, + 0x00, 0x05, 0x00, 0x85, 0x00, 0xe5, 0x10, 0x00, + 0x05, 0x00, 0xe5, 0x02, 0x06, 0x25, 0xe6, 0x01, + 0x05, 0x20, 0x85, 0x00, 0x04, 0x00, 0xa6, 0x20, + 0xe9, 0x02, 0x20, 0x65, 0xe0, 0x18, 0x05, 0x4f, + 0xf6, 0x07, 0x0f, 0x16, 0x4f, 0x26, 0xaf, 0xe9, + 0x02, 0xeb, 0x02, 0x0f, 0x06, 0x0f, 0x06, 0x0f, + 0x06, 0x12, 0x13, 0x12, 0x13, 0x27, 0xe5, 0x00, + 0x00, 0xe5, 0x1c, 0x60, 0xe6, 0x06, 0x07, 0x86, + 0x16, 0x26, 0x85, 0xe6, 0x03, 0x00, 0xe6, 0x1c, + 0x00, 0xef, 0x00, 0x06, 0xaf, 0x00, 0x2f, 0x96, + 0x6f, 0x36, 0xe0, 0x1d, 0xe5, 0x23, 0x27, 0x66, + 0x07, 0xa6, 0x07, 0x26, 0x27, 0x26, 0x05, 0xe9, + 0x02, 0xb6, 0xa5, 0x27, 0x26, 0x65, 0x46, 0x05, + 0x47, 0x25, 0xc7, 0x45, 0x66, 0xe5, 0x05, 0x06, + 0x27, 0x26, 0xa7, 0x06, 0x05, 0x07, 0xe9, 0x02, + 0x47, 0x06, 0x2f, 0xe1, 0x1e, 0x00, 0x01, 0x80, + 0x01, 0x20, 0xe2, 0x23, 0x16, 0x04, 0x42, 0xe5, + 0x80, 0xc1, 0x00, 0x65, 0x20, 0xc5, 0x00, 0x05, + 0x00, 0x65, 0x20, 0xe5, 0x21, 0x00, 0x65, 0x20, + 0xe5, 0x19, 0x00, 0x65, 0x20, 0xc5, 0x00, 0x05, + 0x00, 0x65, 0x20, 0xe5, 0x07, 0x00, 0xe5, 0x31, + 0x00, 0x65, 0x20, 0xe5, 0x3b, 0x20, 0x46, 0xf6, + 0x01, 0xeb, 0x0c, 0x40, 0xe5, 0x08, 0xef, 0x02, + 0xa0, 0xe1, 0x4e, 0x20, 0xa2, 0x20, 0x11, 0xe5, + 0x81, 0xe4, 0x0f, 0x16, 0xe5, 0x09, 0x17, 0xe5, + 0x12, 0x12, 0x13, 0x40, 0xe5, 0x43, 0x56, 0x4a, + 0xe5, 0x00, 0xc0, 0xe5, 0x0a, 0x46, 0x07, 0xe0, + 0x01, 0xe5, 0x0b, 0x26, 0x07, 0x36, 0xe0, 0x01, + 0xe5, 0x0a, 0x26, 0xe0, 0x04, 0xe5, 0x05, 0x00, + 0x45, 0x00, 0x26, 0xe0, 0x04, 0xe5, 0x2c, 0x26, + 0x07, 0xc6, 0xe7, 0x00, 0x06, 0x27, 0xe6, 0x03, + 0x56, 0x04, 0x56, 0x0d, 0x05, 0x06, 0x20, 0xe9, + 0x02, 0xa0, 0xeb, 0x02, 0xa0, 0xb6, 0x11, 0x76, + 0x46, 0x1b, 0x06, 0xe9, 0x02, 0xa0, 0xe5, 0x1b, + 0x04, 0xe5, 0x2d, 0xc0, 0x85, 0x26, 0xe5, 0x1a, + 0x06, 0x05, 0x80, 0xe5, 0x3e, 0xe0, 0x02, 0xe5, + 0x17, 0x00, 0x46, 0x67, 0x26, 0x47, 0x60, 0x27, + 0x06, 0xa7, 0x46, 0x60, 0x0f, 0x40, 0x36, 0xe9, + 0x02, 0xe5, 0x16, 0x20, 0x85, 0xe0, 0x03, 0xe5, + 0x24, 0x60, 0xe5, 0x12, 0xa0, 0xe9, 0x02, 0x0b, + 0x40, 0xef, 0x1a, 0xe5, 0x0f, 0x26, 0x27, 0x06, + 0x20, 0x36, 0xe5, 0x2d, 0x07, 0x06, 0x07, 0xc6, + 0x00, 0x06, 0x07, 0x06, 0x27, 0xe6, 0x00, 0xa7, + 0xe6, 0x02, 0x20, 0x06, 0xe9, 0x02, 0xa0, 0xe9, + 0x02, 0xa0, 0xd6, 0x04, 0xb6, 0x20, 0xe6, 0x06, + 0x08, 0xe6, 0x08, 0xe0, 0x29, 0x66, 0x07, 0xe5, + 0x27, 0x06, 0x07, 0x86, 0x07, 0x06, 0x87, 0x06, + 0x27, 0xe5, 0x00, 0x40, 0xe9, 0x02, 0xd6, 0xef, + 0x02, 0xe6, 0x01, 0xef, 0x01, 0x36, 0x00, 0x26, + 0x07, 0xe5, 0x16, 0x07, 0x66, 0x27, 0x26, 0x07, + 0x46, 0x25, 0xe9, 0x02, 0xe5, 0x24, 0x06, 0x07, + 0x26, 0x47, 0x06, 0x07, 0x46, 0x27, 0xe0, 0x00, + 0x76, 0xe5, 0x1c, 0xe7, 0x00, 0xe6, 0x00, 0x27, + 0x26, 0x40, 0x96, 0xe9, 0x02, 0x40, 0x45, 0xe9, + 0x02, 0xe5, 0x16, 0xa4, 0x36, 0xe2, 0x01, 0xc0, + 0xe1, 0x23, 0x20, 0x41, 0xf6, 0x00, 0xe0, 0x00, + 0x46, 0x16, 0xe6, 0x05, 0x07, 0xc6, 0x65, 0x06, + 0xa5, 0x06, 0x25, 0x07, 0x26, 0x05, 0x80, 0xe2, + 0x24, 0xe4, 0x37, 0xe2, 0x05, 0x04, 0xe2, 0x1a, + 0xe4, 0x1d, 0xe6, 0x38, 0xff, 0x80, 0x0e, 0xe2, + 0x00, 0xff, 0x5a, 0xe2, 0x00, 0xe1, 0x00, 0xa2, + 0x20, 0xa1, 0x20, 0xe2, 0x00, 0xe1, 0x00, 0xe2, + 0x00, 0xe1, 0x00, 0xa2, 0x20, 0xa1, 0x20, 0xe2, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x3f, 0xc2, 0xe1, 0x00, 0xe2, 0x06, 0x20, 0xe2, + 0x00, 0xe3, 0x00, 0xe2, 0x00, 0xe3, 0x00, 0xe2, + 0x00, 0xe3, 0x00, 0x82, 0x00, 0x22, 0x61, 0x03, + 0x0e, 0x02, 0x4e, 0x42, 0x00, 0x22, 0x61, 0x03, + 0x4e, 0x62, 0x20, 0x22, 0x61, 0x00, 0x4e, 0xe2, + 0x00, 0x81, 0x4e, 0x20, 0x42, 0x00, 0x22, 0x61, + 0x03, 0x2e, 0x00, 0xf7, 0x03, 0x9b, 0xb1, 0x36, + 0x14, 0x15, 0x12, 0x34, 0x15, 0x12, 0x14, 0xf6, + 0x00, 0x18, 0x19, 0x9b, 0x17, 0xf6, 0x01, 0x14, + 0x15, 0x76, 0x30, 0x56, 0x0c, 0x12, 0x13, 0xf6, + 0x03, 0x0c, 0x16, 0x10, 0xf6, 0x02, 0x17, 0x9b, + 0x00, 0xfb, 0x02, 0x0b, 0x04, 0x20, 0xab, 0x4c, + 0x12, 0x13, 0x04, 0xeb, 0x02, 0x4c, 0x12, 0x13, + 0x00, 0xe4, 0x05, 0x40, 0xed, 0x19, 0xe0, 0x07, + 0xe6, 0x05, 0x68, 0x06, 0x48, 0xe6, 0x04, 0xe0, + 0x07, 0x2f, 0x01, 0x6f, 0x01, 0x2f, 0x02, 0x41, + 0x22, 0x41, 0x02, 0x0f, 0x01, 0x2f, 0x0c, 0x81, + 0xaf, 0x01, 0x0f, 0x01, 0x0f, 0x01, 0x0f, 0x61, + 0x0f, 0x02, 0x61, 0x02, 0x65, 0x02, 0x2f, 0x22, + 0x21, 0x8c, 0x3f, 0x42, 0x0f, 0x0c, 0x2f, 0x02, + 0x0f, 0xeb, 0x08, 0xea, 0x1b, 0x3f, 0x6a, 0x0b, + 0x2f, 0x60, 0x8c, 0x8f, 0x2c, 0x6f, 0x0c, 0x2f, + 0x0c, 0x2f, 0x0c, 0xcf, 0x0c, 0xef, 0x17, 0x2c, + 0x2f, 0x0c, 0x0f, 0x0c, 0xef, 0x17, 0xec, 0x80, + 0x84, 0xef, 0x00, 0x12, 0x13, 0x12, 0x13, 0xef, + 0x0c, 0x2c, 0xcf, 0x12, 0x13, 0xef, 0x49, 0x0c, + 0xef, 0x16, 0xec, 0x11, 0xef, 0x20, 0xac, 0xef, + 0x3d, 0xe0, 0x11, 0xef, 0x03, 0xe0, 0x0d, 0xeb, + 0x34, 0xef, 0x46, 0xeb, 0x0e, 0xef, 0x80, 0x2f, + 0x0c, 0xef, 0x01, 0x0c, 0xef, 0x2e, 0xec, 0x00, + 0xef, 0x67, 0x0c, 0xef, 0x80, 0x70, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0xeb, 0x16, 0xef, 0x24, + 0x8c, 0x12, 0x13, 0xec, 0x17, 0x12, 0x13, 0x12, + 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0xec, + 0x08, 0xef, 0x80, 0x78, 0xec, 0x7b, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0xec, 0x37, 0x12, 0x13, + 0x12, 0x13, 0xec, 0x18, 0x12, 0x13, 0xec, 0x80, + 0x7a, 0xef, 0x28, 0xec, 0x0d, 0x2f, 0xac, 0xef, + 0x1f, 0x20, 0xef, 0x18, 0x00, 0xef, 0x61, 0xe1, + 0x28, 0xe2, 0x28, 0x5f, 0x21, 0x22, 0xdf, 0x41, + 0x02, 0x3f, 0x02, 0x3f, 0x82, 0x24, 0x41, 0x02, + 0xff, 0x5a, 0x02, 0xaf, 0x7f, 0x46, 0x3f, 0x80, + 0x76, 0x0b, 0x36, 0xe2, 0x1e, 0x00, 0x02, 0x80, + 0x02, 0x20, 0xe5, 0x30, 0xc0, 0x04, 0x16, 0xe0, + 0x06, 0x06, 0xe5, 0x0f, 0xe0, 0x01, 0xc5, 0x00, + 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, + 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xe6, 0x18, + 0x36, 0x14, 0x15, 0x14, 0x15, 0x56, 0x14, 0x15, + 0x16, 0x14, 0x15, 0xf6, 0x01, 0x11, 0x36, 0x11, + 0x16, 0x14, 0x15, 0x36, 0x14, 0x15, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x96, 0x04, + 0xf6, 0x02, 0x31, 0x76, 0x11, 0x16, 0x12, 0xf6, + 0x05, 0x2f, 0x56, 0x12, 0x13, 0x12, 0x13, 0x12, + 0x13, 0x12, 0x13, 0x11, 0xe0, 0x1a, 0xef, 0x12, + 0x00, 0xef, 0x51, 0xe0, 0x04, 0xef, 0x80, 0x4e, + 0xe0, 0x12, 0xef, 0x04, 0x60, 0x17, 0x56, 0x0f, + 0x04, 0x05, 0x0a, 0x12, 0x13, 0x12, 0x13, 0x12, + 0x13, 0x12, 0x13, 0x12, 0x13, 0x2f, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x11, 0x12, + 0x33, 0x0f, 0xea, 0x01, 0x66, 0x27, 0x11, 0x84, + 0x2f, 0x4a, 0x04, 0x05, 0x16, 0x2f, 0x00, 0xe5, + 0x4e, 0x20, 0x26, 0x2e, 0x24, 0x05, 0x11, 0xe5, + 0x52, 0x16, 0x44, 0x05, 0x80, 0xe5, 0x23, 0x00, + 0xe5, 0x56, 0x00, 0x2f, 0x6b, 0xef, 0x02, 0xe5, + 0x18, 0xef, 0x1c, 0xe0, 0x04, 0xe5, 0x08, 0xef, + 0x17, 0x00, 0xeb, 0x02, 0xef, 0x16, 0xeb, 0x00, + 0x0f, 0xeb, 0x07, 0xef, 0x18, 0xeb, 0x02, 0xef, + 0x1f, 0xeb, 0x07, 0xef, 0x80, 0xb8, 0xe5, 0x99, + 0x38, 0xef, 0x38, 0xe5, 0xc0, 0x11, 0x8d, 0x04, + 0xe5, 0x83, 0xef, 0x40, 0xef, 0x2f, 0xe0, 0x01, + 0xe5, 0x20, 0xa4, 0x36, 0xe5, 0x80, 0x84, 0x04, + 0x56, 0xe5, 0x08, 0xe9, 0x02, 0x25, 0xe0, 0x0c, + 0xff, 0x26, 0x05, 0x06, 0x48, 0x16, 0xe6, 0x02, + 0x16, 0x04, 0xff, 0x14, 0x24, 0x26, 0xe5, 0x3e, + 0xea, 0x02, 0x26, 0xb6, 0xe0, 0x00, 0xee, 0x0f, + 0xe4, 0x01, 0x2e, 0xff, 0x06, 0x22, 0xff, 0x36, + 0x04, 0xe2, 0x00, 0x9f, 0xff, 0x02, 0x04, 0x2e, + 0x7f, 0x05, 0x7f, 0x22, 0xff, 0x0d, 0x61, 0x02, + 0x81, 0x02, 0xff, 0x07, 0x41, 0x02, 0x3f, 0x80, + 0x3f, 0x00, 0x02, 0x00, 0x02, 0x7f, 0xe0, 0x10, + 0x44, 0x3f, 0x05, 0x24, 0x02, 0xc5, 0x06, 0x45, + 0x06, 0x65, 0x06, 0xe5, 0x0f, 0x27, 0x26, 0x07, + 0x6f, 0x06, 0x40, 0xab, 0x2f, 0x0d, 0x0f, 0xa0, + 0xe5, 0x2c, 0x76, 0xe0, 0x00, 0x27, 0xe5, 0x2a, + 0xe7, 0x08, 0x26, 0xe0, 0x00, 0x36, 0xe9, 0x02, + 0xa0, 0xe6, 0x0a, 0xa5, 0x56, 0x05, 0x16, 0x25, + 0x06, 0xe9, 0x02, 0xe5, 0x14, 0xe6, 0x00, 0x36, + 0xe5, 0x0f, 0xe6, 0x03, 0x27, 0xe0, 0x03, 0x16, + 0xe5, 0x15, 0x40, 0x46, 0x07, 0xe5, 0x27, 0x06, + 0x27, 0x66, 0x27, 0x26, 0x47, 0xf6, 0x05, 0x00, + 0x04, 0xe9, 0x02, 0x60, 0x36, 0x85, 0x06, 0x04, + 0xe5, 0x01, 0xe9, 0x02, 0x85, 0x00, 0xe5, 0x21, + 0xa6, 0x27, 0x26, 0x27, 0x26, 0xe0, 0x01, 0x45, + 0x06, 0xe5, 0x00, 0x06, 0x07, 0x20, 0xe9, 0x02, + 0x20, 0x76, 0xe5, 0x08, 0x04, 0xa5, 0x4f, 0x05, + 0x07, 0x06, 0x07, 0xe5, 0x2a, 0x06, 0x05, 0x46, + 0x25, 0x26, 0x85, 0x26, 0x05, 0x06, 0x05, 0xe0, + 0x10, 0x25, 0x04, 0x36, 0xe5, 0x03, 0x07, 0x26, + 0x27, 0x36, 0x05, 0x24, 0x07, 0x06, 0xe0, 0x02, + 0xa5, 0x20, 0xa5, 0x20, 0xa5, 0xe0, 0x01, 0xc5, + 0x00, 0xc5, 0x00, 0xe2, 0x23, 0x0e, 0x64, 0xe2, + 0x01, 0x04, 0x2e, 0x60, 0xe2, 0x48, 0xe5, 0x1b, + 0x27, 0x06, 0x27, 0x06, 0x27, 0x16, 0x07, 0x06, + 0x20, 0xe9, 0x02, 0xa0, 0xe5, 0xab, 0x1c, 0xe0, + 0x04, 0xe5, 0x0f, 0x60, 0xe5, 0x29, 0x60, 0xfc, + 0x87, 0x78, 0xfd, 0x98, 0x78, 0xe5, 0x80, 0xe6, + 0x20, 0xe5, 0x62, 0xe0, 0x1e, 0xc2, 0xe0, 0x04, + 0x82, 0x80, 0x05, 0x06, 0xe5, 0x02, 0x0c, 0xe5, + 0x05, 0x00, 0x85, 0x00, 0x05, 0x00, 0x25, 0x00, + 0x25, 0x00, 0xe5, 0x64, 0xee, 0x09, 0xe0, 0x08, + 0xe5, 0x80, 0xe3, 0x13, 0x12, 0xef, 0x08, 0xe5, + 0x38, 0x20, 0xe5, 0x2e, 0xc0, 0x0f, 0xe0, 0x18, + 0xe5, 0x04, 0x0d, 0x4f, 0xe6, 0x08, 0xd6, 0x12, + 0x13, 0x16, 0xa0, 0xe6, 0x08, 0x16, 0x31, 0x30, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0x36, 0x12, 0x13, 0x76, 0x50, 0x56, 0x00, 0x76, + 0x11, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x56, + 0x0c, 0x11, 0x4c, 0x00, 0x16, 0x0d, 0x36, 0x60, + 0x85, 0x00, 0xe5, 0x7f, 0x20, 0x1b, 0x00, 0x56, + 0x0d, 0x56, 0x12, 0x13, 0x16, 0x0c, 0x16, 0x11, + 0x36, 0xe9, 0x02, 0x36, 0x4c, 0x36, 0xe1, 0x12, + 0x12, 0x16, 0x13, 0x0e, 0x10, 0x0e, 0xe2, 0x12, + 0x12, 0x0c, 0x13, 0x0c, 0x12, 0x13, 0x16, 0x12, + 0x13, 0x36, 0xe5, 0x02, 0x04, 0xe5, 0x25, 0x24, + 0xe5, 0x17, 0x40, 0xa5, 0x20, 0xa5, 0x20, 0xa5, + 0x20, 0x45, 0x40, 0x2d, 0x0c, 0x0e, 0x0f, 0x2d, + 0x00, 0x0f, 0x6c, 0x2f, 0xe0, 0x02, 0x5b, 0x2f, + 0x20, 0xe5, 0x04, 0x00, 0xe5, 0x12, 0x00, 0xe5, + 0x0b, 0x00, 0x25, 0x00, 0xe5, 0x07, 0x20, 0xe5, + 0x06, 0xe0, 0x1a, 0xe5, 0x73, 0x80, 0x56, 0x60, + 0xeb, 0x25, 0x40, 0xef, 0x01, 0xea, 0x2d, 0x6b, + 0xef, 0x09, 0x2b, 0x4f, 0x00, 0xef, 0x05, 0x40, + 0x0f, 0xe0, 0x27, 0xef, 0x25, 0x06, 0xe0, 0x7a, + 0xe5, 0x15, 0x40, 0xe5, 0x29, 0xe0, 0x07, 0x06, + 0xeb, 0x13, 0x60, 0xe5, 0x18, 0x6b, 0xe0, 0x01, + 0xe5, 0x0c, 0x0a, 0xe5, 0x00, 0x0a, 0x80, 0xe5, + 0x1e, 0x86, 0x80, 0xe5, 0x16, 0x00, 0x16, 0xe5, + 0x1c, 0x60, 0xe5, 0x00, 0x16, 0x8a, 0xe0, 0x22, + 0xe1, 0x20, 0xe2, 0x20, 0xe5, 0x46, 0x20, 0xe9, + 0x02, 0xa0, 0xe1, 0x1c, 0x60, 0xe2, 0x1c, 0x60, + 0xe5, 0x20, 0xe0, 0x00, 0xe5, 0x2c, 0xe0, 0x03, + 0x16, 0xe1, 0x03, 0x00, 0xe1, 0x07, 0x00, 0xc1, + 0x00, 0x21, 0x00, 0xe2, 0x03, 0x00, 0xe2, 0x07, + 0x00, 0xc2, 0x00, 0x22, 0xe0, 0x3b, 0xe5, 0x80, + 0xaf, 0xe0, 0x01, 0xe5, 0x0e, 0xe0, 0x02, 0xe5, + 0x00, 0xe0, 0x10, 0xa4, 0x00, 0xe4, 0x22, 0x00, + 0xe4, 0x01, 0xe0, 0x3d, 0xa5, 0x20, 0x05, 0x00, + 0xe5, 0x24, 0x00, 0x25, 0x40, 0x05, 0x20, 0xe5, + 0x0f, 0x00, 0x16, 0xeb, 0x00, 0xe5, 0x0f, 0x2f, + 0xcb, 0xe5, 0x17, 0xe0, 0x00, 0xeb, 0x01, 0xe0, + 0x28, 0xe5, 0x0b, 0x00, 0x25, 0x80, 0x8b, 0xe5, + 0x0e, 0xab, 0x40, 0x16, 0xe5, 0x12, 0x80, 0x16, + 0xe0, 0x38, 0xe5, 0x30, 0x60, 0x2b, 0x25, 0xeb, + 0x08, 0x20, 0xeb, 0x26, 0x05, 0x46, 0x00, 0x26, + 0x80, 0x66, 0x65, 0x00, 0x45, 0x00, 0xe5, 0x15, + 0x20, 0x46, 0x60, 0x06, 0xeb, 0x01, 0xc0, 0xf6, + 0x01, 0xc0, 0xe5, 0x15, 0x2b, 0x16, 0xe5, 0x15, + 0x4b, 0xe0, 0x18, 0xe5, 0x00, 0x0f, 0xe5, 0x14, + 0x26, 0x60, 0x8b, 0xd6, 0xe0, 0x01, 0xe5, 0x2e, + 0x40, 0xd6, 0xe5, 0x0e, 0x20, 0xeb, 0x00, 0xe5, + 0x0b, 0x80, 0xeb, 0x00, 0xe5, 0x0a, 0xc0, 0x76, + 0xe0, 0x04, 0xcb, 0xe0, 0x48, 0xe5, 0x41, 0xe0, + 0x2f, 0xe1, 0x2b, 0xe0, 0x05, 0xe2, 0x2b, 0xc0, + 0xab, 0xe5, 0x1c, 0x66, 0xe0, 0x00, 0xe9, 0x02, + 0xe0, 0x80, 0x9e, 0xeb, 0x17, 0x00, 0xe5, 0x22, + 0x00, 0x26, 0x11, 0x20, 0x25, 0xe0, 0x46, 0xe5, + 0x15, 0xeb, 0x02, 0x05, 0xe0, 0x00, 0xe5, 0x0e, + 0xe6, 0x03, 0x6b, 0x96, 0xe0, 0x0e, 0xe5, 0x0a, + 0x66, 0x76, 0xe0, 0x1e, 0xe5, 0x0d, 0xcb, 0xe0, + 0x0c, 0xe5, 0x0f, 0xe0, 0x01, 0x07, 0x06, 0x07, + 0xe5, 0x2d, 0xe6, 0x07, 0xd6, 0x60, 0xeb, 0x0c, + 0xe9, 0x02, 0x06, 0x25, 0x26, 0x05, 0xe0, 0x01, + 0x46, 0x07, 0xe5, 0x25, 0x47, 0x66, 0x27, 0x26, + 0x36, 0x1b, 0x76, 0x06, 0xe0, 0x02, 0x1b, 0x20, + 0xe5, 0x11, 0xc0, 0xe9, 0x02, 0xa0, 0x46, 0xe5, + 0x1c, 0x86, 0x07, 0xe6, 0x00, 0x00, 0xe9, 0x02, + 0x76, 0x05, 0x27, 0x05, 0xe0, 0x00, 0xe5, 0x1b, + 0x06, 0x36, 0x05, 0xe0, 0x01, 0x26, 0x07, 0xe5, + 0x28, 0x47, 0xe6, 0x01, 0x27, 0x65, 0x76, 0x66, + 0x16, 0x07, 0x06, 0xe9, 0x02, 0x05, 0x16, 0x05, + 0x56, 0x00, 0xeb, 0x0c, 0xe0, 0x03, 0xe5, 0x0a, + 0x00, 0xe5, 0x11, 0x47, 0x46, 0x27, 0x06, 0x07, + 0x26, 0xb6, 0x06, 0xe0, 0x39, 0xc5, 0x00, 0x05, + 0x00, 0x65, 0x00, 0xe5, 0x07, 0x00, 0xe5, 0x02, + 0x16, 0xa0, 0xe5, 0x27, 0x06, 0x47, 0xe6, 0x00, + 0x80, 0xe9, 0x02, 0xa0, 0x26, 0x27, 0x00, 0xe5, + 0x00, 0x20, 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, + 0x00, 0x25, 0x00, 0x85, 0x00, 0x26, 0x05, 0x27, + 0x06, 0x67, 0x20, 0x27, 0x20, 0x47, 0x20, 0x05, + 0xa0, 0x07, 0x80, 0x85, 0x27, 0x20, 0xc6, 0x40, + 0x86, 0xe0, 0x80, 0x03, 0xe5, 0x2d, 0x47, 0xe6, + 0x00, 0x27, 0x46, 0x07, 0x06, 0x65, 0x96, 0xe9, + 0x02, 0x36, 0x00, 0x16, 0x06, 0x45, 0xe0, 0x16, + 0xe5, 0x28, 0x47, 0xa6, 0x07, 0x06, 0x67, 0x26, + 0x07, 0x26, 0x25, 0x16, 0x05, 0xe0, 0x00, 0xe9, + 0x02, 0xe0, 0x80, 0x1e, 0xe5, 0x27, 0x47, 0x66, + 0x20, 0x67, 0x26, 0x07, 0x26, 0xf6, 0x0f, 0x65, + 0x26, 0xe0, 0x1a, 0xe5, 0x28, 0x47, 0xe6, 0x00, + 0x27, 0x06, 0x07, 0x26, 0x56, 0x05, 0xe0, 0x03, + 0xe9, 0x02, 0xa0, 0xf6, 0x05, 0xe0, 0x0b, 0xe5, + 0x23, 0x06, 0x07, 0x06, 0x27, 0xa6, 0x07, 0x06, + 0x05, 0x16, 0xa0, 0xe9, 0x02, 0xe0, 0x2e, 0xe5, + 0x13, 0x20, 0x46, 0x27, 0x66, 0x07, 0x86, 0x60, + 0xe9, 0x02, 0x2b, 0x56, 0x0f, 0xc5, 0xe0, 0x80, + 0x31, 0xe5, 0x24, 0x47, 0xe6, 0x01, 0x07, 0x26, + 0x16, 0xe0, 0x5c, 0xe1, 0x18, 0xe2, 0x18, 0xe9, + 0x02, 0xeb, 0x01, 0xe0, 0x04, 0xe5, 0x00, 0x20, + 0x05, 0x20, 0xe5, 0x00, 0x00, 0x25, 0x00, 0xe5, + 0x10, 0xa7, 0x00, 0x27, 0x20, 0x26, 0x07, 0x06, + 0x05, 0x07, 0x05, 0x07, 0x06, 0x56, 0xe0, 0x01, + 0xe9, 0x02, 0xe0, 0x3e, 0xe5, 0x00, 0x20, 0xe5, + 0x1f, 0x47, 0x66, 0x20, 0x26, 0x67, 0x06, 0x05, + 0x16, 0x05, 0x07, 0xe0, 0x13, 0x05, 0xe6, 0x02, + 0xe5, 0x20, 0xa6, 0x07, 0x05, 0x66, 0xf6, 0x00, + 0x06, 0xe0, 0x00, 0x05, 0xa6, 0x27, 0x46, 0xe5, + 0x26, 0xe6, 0x05, 0x07, 0x26, 0x56, 0x05, 0x96, + 0xe0, 0x05, 0xe5, 0x41, 0xe0, 0x80, 0x7f, 0xe5, + 0x01, 0x00, 0xe5, 0x1d, 0x07, 0xc6, 0x00, 0xa6, + 0x07, 0x06, 0x05, 0x96, 0xe0, 0x02, 0xe9, 0x02, + 0xeb, 0x0b, 0x40, 0x36, 0xe5, 0x16, 0x20, 0xe6, + 0x0e, 0x00, 0x07, 0xc6, 0x07, 0x26, 0x07, 0x26, + 0xe0, 0x41, 0xc5, 0x00, 0x25, 0x00, 0xe5, 0x1e, + 0xa6, 0x40, 0x06, 0x00, 0x26, 0x00, 0xc6, 0x05, + 0x06, 0xe0, 0x00, 0xe9, 0x02, 0xa0, 0xa5, 0x00, + 0x25, 0x00, 0xe5, 0x18, 0x87, 0x00, 0x26, 0x00, + 0x27, 0x06, 0x07, 0x06, 0x05, 0xc0, 0xe9, 0x02, + 0xe0, 0x80, 0xae, 0xe5, 0x0b, 0x26, 0x27, 0x36, + 0xe0, 0x80, 0x2f, 0x05, 0xe0, 0x07, 0xeb, 0x0d, + 0xef, 0x00, 0x6d, 0xef, 0x09, 0xe0, 0x05, 0x16, + 0xe5, 0x83, 0x12, 0xe0, 0x5e, 0xea, 0x67, 0x00, + 0x96, 0xe0, 0x03, 0xe5, 0x80, 0x3c, 0xe0, 0x89, + 0xc4, 0xe5, 0x59, 0x36, 0xe0, 0x05, 0xe5, 0x83, + 0xa7, 0x00, 0xfb, 0x01, 0xe0, 0x8f, 0x3f, 0xe5, + 0x81, 0xbf, 0xe0, 0xa1, 0x31, 0xe5, 0x81, 0xb1, + 0xc0, 0xe5, 0x17, 0x00, 0xe9, 0x02, 0x60, 0x36, + 0xe5, 0x47, 0x00, 0xe9, 0x02, 0xa0, 0xe5, 0x16, + 0x20, 0x86, 0x16, 0xe0, 0x02, 0xe5, 0x28, 0xc6, + 0x96, 0x6f, 0x64, 0x16, 0x0f, 0xe0, 0x02, 0xe9, + 0x02, 0x00, 0xcb, 0x00, 0xe5, 0x0d, 0x80, 0xe5, + 0x0b, 0xe0, 0x82, 0x28, 0xe1, 0x18, 0xe2, 0x18, + 0xeb, 0x0f, 0x76, 0xe0, 0x5d, 0xe5, 0x43, 0x60, + 0x06, 0x05, 0xe7, 0x2f, 0xc0, 0x66, 0xe4, 0x05, + 0xe0, 0x38, 0x24, 0x16, 0x04, 0x06, 0xe0, 0x03, + 0x27, 0xe0, 0x06, 0xe5, 0x97, 0x70, 0xe0, 0x00, + 0xe5, 0x84, 0x4e, 0xe0, 0x22, 0xe5, 0x01, 0xe0, + 0xa2, 0x5f, 0x64, 0x00, 0xc4, 0x00, 0x24, 0x00, + 0xe5, 0x80, 0x9b, 0xe0, 0x25, 0x45, 0xe0, 0x09, + 0x65, 0xe0, 0x00, 0xe5, 0x81, 0x04, 0xe0, 0x88, + 0x7c, 0xe5, 0x63, 0x80, 0xe5, 0x05, 0x40, 0xe5, + 0x01, 0xc0, 0xe5, 0x02, 0x20, 0x0f, 0x26, 0x16, + 0x7b, 0xe0, 0x91, 0xd4, 0xe6, 0x26, 0x20, 0xe6, + 0x0f, 0xe0, 0x01, 0xef, 0x6c, 0xe0, 0x34, 0xef, + 0x80, 0x6e, 0xe0, 0x02, 0xef, 0x1f, 0x20, 0xef, + 0x34, 0x27, 0x46, 0x4f, 0xa7, 0xfb, 0x00, 0xe6, + 0x00, 0x2f, 0xc6, 0xef, 0x16, 0x66, 0xef, 0x35, + 0xe0, 0x0d, 0xef, 0x3a, 0x46, 0x0f, 0xe0, 0x80, + 0x12, 0xeb, 0x0c, 0xe0, 0x04, 0xef, 0x4f, 0xe0, + 0x01, 0xeb, 0x11, 0xe0, 0x7f, 0xe1, 0x12, 0xe2, + 0x12, 0xe1, 0x12, 0xc2, 0x00, 0xe2, 0x0a, 0xe1, + 0x12, 0xe2, 0x12, 0x01, 0x00, 0x21, 0x20, 0x01, + 0x20, 0x21, 0x20, 0x61, 0x00, 0xe1, 0x00, 0x62, + 0x00, 0x02, 0x00, 0xc2, 0x00, 0xe2, 0x03, 0xe1, + 0x12, 0xe2, 0x12, 0x21, 0x00, 0x61, 0x20, 0xe1, + 0x00, 0x00, 0xc1, 0x00, 0xe2, 0x12, 0x21, 0x00, + 0x61, 0x00, 0x81, 0x00, 0x01, 0x40, 0xc1, 0x00, + 0xe2, 0x12, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, + 0xe2, 0x12, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, + 0xe2, 0x12, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, + 0xe2, 0x14, 0x20, 0xe1, 0x11, 0x0c, 0xe2, 0x11, + 0x0c, 0xa2, 0xe1, 0x11, 0x0c, 0xe2, 0x11, 0x0c, + 0xa2, 0xe1, 0x11, 0x0c, 0xe2, 0x11, 0x0c, 0xa2, + 0xe1, 0x11, 0x0c, 0xe2, 0x11, 0x0c, 0xa2, 0xe1, + 0x11, 0x0c, 0xe2, 0x11, 0x0c, 0xa2, 0x3f, 0x20, + 0xe9, 0x2a, 0xef, 0x81, 0x78, 0xe6, 0x2f, 0x6f, + 0xe6, 0x2a, 0xef, 0x00, 0x06, 0xef, 0x06, 0x06, + 0x2f, 0x96, 0xe0, 0x07, 0x86, 0x00, 0xe6, 0x07, + 0xe0, 0x83, 0xc8, 0xe2, 0x02, 0x05, 0xe2, 0x0c, + 0xe0, 0x80, 0x59, 0xc6, 0x00, 0xe6, 0x09, 0x20, + 0xc6, 0x00, 0x26, 0x00, 0x86, 0xe0, 0x80, 0x4d, + 0xe5, 0x25, 0x40, 0xc6, 0xc4, 0x20, 0xe9, 0x02, + 0x60, 0x05, 0x0f, 0xe0, 0x80, 0xb8, 0xe5, 0x16, + 0x06, 0xe0, 0x09, 0xe5, 0x24, 0x66, 0xe9, 0x02, + 0x80, 0x0d, 0xe0, 0x84, 0x58, 0xc5, 0x00, 0x65, + 0x00, 0x25, 0x00, 0xe5, 0x07, 0x00, 0xe5, 0x80, + 0x3d, 0x20, 0xeb, 0x01, 0xc6, 0xe0, 0x21, 0xe1, + 0x1a, 0xe2, 0x1a, 0xc6, 0x04, 0x60, 0xe9, 0x02, + 0x60, 0x36, 0xe0, 0x82, 0x89, 0xeb, 0x33, 0x0f, + 0x4b, 0x0d, 0x6b, 0xe0, 0x44, 0xeb, 0x25, 0x0f, + 0xeb, 0x07, 0xe0, 0x80, 0x3a, 0x65, 0x00, 0xe5, + 0x13, 0x00, 0x25, 0x00, 0x05, 0x20, 0x05, 0x00, + 0xe5, 0x02, 0x00, 0x65, 0x00, 0x05, 0x00, 0x05, + 0xa0, 0x05, 0x60, 0x05, 0x00, 0x05, 0x00, 0x05, + 0x00, 0x45, 0x00, 0x25, 0x00, 0x05, 0x20, 0x05, + 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, + 0x00, 0x25, 0x00, 0x05, 0x20, 0x65, 0x00, 0xc5, + 0x00, 0x65, 0x00, 0x65, 0x00, 0x05, 0x00, 0xe5, + 0x02, 0x00, 0xe5, 0x09, 0x80, 0x45, 0x00, 0x85, + 0x00, 0xe5, 0x09, 0xe0, 0x2c, 0x2c, 0xe0, 0x80, + 0x86, 0xef, 0x24, 0x60, 0xef, 0x5c, 0xe0, 0x04, + 0xef, 0x07, 0x20, 0xef, 0x07, 0x00, 0xef, 0x07, + 0x00, 0xef, 0x1d, 0xe0, 0x02, 0xeb, 0x05, 0xef, + 0x80, 0x19, 0xe0, 0x30, 0xef, 0x15, 0xe0, 0x05, + 0xef, 0x24, 0x60, 0xef, 0x01, 0xc0, 0x2f, 0xe0, + 0x06, 0xaf, 0xe0, 0x80, 0x12, 0xef, 0x80, 0x73, + 0x8e, 0xef, 0x82, 0x50, 0x80, 0xef, 0x08, 0x40, + 0xef, 0x05, 0x40, 0xef, 0x6c, 0xe0, 0x04, 0xef, + 0x51, 0xc0, 0xef, 0x04, 0x60, 0x0f, 0xe0, 0x07, + 0xef, 0x04, 0x60, 0xef, 0x30, 0xe0, 0x00, 0xef, + 0x02, 0xa0, 0xef, 0x20, 0xe0, 0x00, 0xef, 0x16, + 0x20, 0x2f, 0xe0, 0x46, 0xef, 0x80, 0xcc, 0xe0, + 0x04, 0xef, 0x06, 0x20, 0x8f, 0x40, 0x8f, 0x40, + 0xcf, 0xe0, 0x01, 0xef, 0x15, 0x40, 0xef, 0x03, + 0x80, 0xaf, 0xe0, 0x02, 0xef, 0x02, 0xa0, 0xef, + 0x00, 0xe0, 0x00, 0xcf, 0xe0, 0x01, 0xef, 0x80, + 0x0b, 0x00, 0xef, 0x2f, 0xe0, 0x1d, 0xe9, 0x02, + 0xe0, 0x83, 0x7e, 0xe5, 0xc0, 0x66, 0x58, 0xe0, + 0x18, 0xe5, 0x8f, 0xb1, 0xc0, 0xe5, 0x80, 0x56, + 0x20, 0xe5, 0x95, 0xfa, 0xe0, 0x06, 0xe5, 0x9c, + 0xa9, 0xe0, 0x8b, 0x97, 0xe5, 0x81, 0x96, 0xe0, + 0x85, 0x5a, 0xe5, 0x92, 0xc3, 0xe0, 0xca, 0xac, + 0x2e, 0x1b, 0xe0, 0x16, 0xfb, 0x58, 0xe0, 0x78, + 0xe6, 0x80, 0x68, 0xe0, 0xc0, 0xbd, 0x88, 0xfd, + 0xc0, 0xbf, 0x76, 0x20, 0xfd, 0xc0, 0xbf, 0x76, + 0x20, +}; + +typedef enum { + UNICODE_SCRIPT_Unknown, + UNICODE_SCRIPT_Adlam, + UNICODE_SCRIPT_Ahom, + UNICODE_SCRIPT_Anatolian_Hieroglyphs, + UNICODE_SCRIPT_Arabic, + UNICODE_SCRIPT_Armenian, + UNICODE_SCRIPT_Avestan, + UNICODE_SCRIPT_Balinese, + UNICODE_SCRIPT_Bamum, + UNICODE_SCRIPT_Bassa_Vah, + UNICODE_SCRIPT_Batak, + UNICODE_SCRIPT_Bengali, + UNICODE_SCRIPT_Bhaiksuki, + UNICODE_SCRIPT_Bopomofo, + UNICODE_SCRIPT_Brahmi, + UNICODE_SCRIPT_Braille, + UNICODE_SCRIPT_Buginese, + UNICODE_SCRIPT_Buhid, + UNICODE_SCRIPT_Canadian_Aboriginal, + UNICODE_SCRIPT_Carian, + UNICODE_SCRIPT_Caucasian_Albanian, + UNICODE_SCRIPT_Chakma, + UNICODE_SCRIPT_Cham, + UNICODE_SCRIPT_Cherokee, + UNICODE_SCRIPT_Chorasmian, + UNICODE_SCRIPT_Common, + UNICODE_SCRIPT_Coptic, + UNICODE_SCRIPT_Cuneiform, + UNICODE_SCRIPT_Cypriot, + UNICODE_SCRIPT_Cyrillic, + UNICODE_SCRIPT_Cypro_Minoan, + UNICODE_SCRIPT_Deseret, + UNICODE_SCRIPT_Devanagari, + UNICODE_SCRIPT_Dives_Akuru, + UNICODE_SCRIPT_Dogra, + UNICODE_SCRIPT_Duployan, + UNICODE_SCRIPT_Egyptian_Hieroglyphs, + UNICODE_SCRIPT_Elbasan, + UNICODE_SCRIPT_Elymaic, + UNICODE_SCRIPT_Ethiopic, + UNICODE_SCRIPT_Georgian, + UNICODE_SCRIPT_Glagolitic, + UNICODE_SCRIPT_Gothic, + UNICODE_SCRIPT_Grantha, + UNICODE_SCRIPT_Greek, + UNICODE_SCRIPT_Gujarati, + UNICODE_SCRIPT_Gunjala_Gondi, + UNICODE_SCRIPT_Gurmukhi, + UNICODE_SCRIPT_Han, + UNICODE_SCRIPT_Hangul, + UNICODE_SCRIPT_Hanifi_Rohingya, + UNICODE_SCRIPT_Hanunoo, + UNICODE_SCRIPT_Hatran, + UNICODE_SCRIPT_Hebrew, + UNICODE_SCRIPT_Hiragana, + UNICODE_SCRIPT_Imperial_Aramaic, + UNICODE_SCRIPT_Inherited, + UNICODE_SCRIPT_Inscriptional_Pahlavi, + UNICODE_SCRIPT_Inscriptional_Parthian, + UNICODE_SCRIPT_Javanese, + UNICODE_SCRIPT_Kaithi, + UNICODE_SCRIPT_Kannada, + UNICODE_SCRIPT_Katakana, + UNICODE_SCRIPT_Kayah_Li, + UNICODE_SCRIPT_Kharoshthi, + UNICODE_SCRIPT_Khmer, + UNICODE_SCRIPT_Khojki, + UNICODE_SCRIPT_Khitan_Small_Script, + UNICODE_SCRIPT_Khudawadi, + UNICODE_SCRIPT_Lao, + UNICODE_SCRIPT_Latin, + UNICODE_SCRIPT_Lepcha, + UNICODE_SCRIPT_Limbu, + UNICODE_SCRIPT_Linear_A, + UNICODE_SCRIPT_Linear_B, + UNICODE_SCRIPT_Lisu, + UNICODE_SCRIPT_Lycian, + UNICODE_SCRIPT_Lydian, + UNICODE_SCRIPT_Makasar, + UNICODE_SCRIPT_Mahajani, + UNICODE_SCRIPT_Malayalam, + UNICODE_SCRIPT_Mandaic, + UNICODE_SCRIPT_Manichaean, + UNICODE_SCRIPT_Marchen, + UNICODE_SCRIPT_Masaram_Gondi, + UNICODE_SCRIPT_Medefaidrin, + UNICODE_SCRIPT_Meetei_Mayek, + UNICODE_SCRIPT_Mende_Kikakui, + UNICODE_SCRIPT_Meroitic_Cursive, + UNICODE_SCRIPT_Meroitic_Hieroglyphs, + UNICODE_SCRIPT_Miao, + UNICODE_SCRIPT_Modi, + UNICODE_SCRIPT_Mongolian, + UNICODE_SCRIPT_Mro, + UNICODE_SCRIPT_Multani, + UNICODE_SCRIPT_Myanmar, + UNICODE_SCRIPT_Nabataean, + UNICODE_SCRIPT_Nandinagari, + UNICODE_SCRIPT_New_Tai_Lue, + UNICODE_SCRIPT_Newa, + UNICODE_SCRIPT_Nko, + UNICODE_SCRIPT_Nushu, + UNICODE_SCRIPT_Nyiakeng_Puachue_Hmong, + UNICODE_SCRIPT_Ogham, + UNICODE_SCRIPT_Ol_Chiki, + UNICODE_SCRIPT_Old_Hungarian, + UNICODE_SCRIPT_Old_Italic, + UNICODE_SCRIPT_Old_North_Arabian, + UNICODE_SCRIPT_Old_Permic, + UNICODE_SCRIPT_Old_Persian, + UNICODE_SCRIPT_Old_Sogdian, + UNICODE_SCRIPT_Old_South_Arabian, + UNICODE_SCRIPT_Old_Turkic, + UNICODE_SCRIPT_Old_Uyghur, + UNICODE_SCRIPT_Oriya, + UNICODE_SCRIPT_Osage, + UNICODE_SCRIPT_Osmanya, + UNICODE_SCRIPT_Pahawh_Hmong, + UNICODE_SCRIPT_Palmyrene, + UNICODE_SCRIPT_Pau_Cin_Hau, + UNICODE_SCRIPT_Phags_Pa, + UNICODE_SCRIPT_Phoenician, + UNICODE_SCRIPT_Psalter_Pahlavi, + UNICODE_SCRIPT_Rejang, + UNICODE_SCRIPT_Runic, + UNICODE_SCRIPT_Samaritan, + UNICODE_SCRIPT_Saurashtra, + UNICODE_SCRIPT_Sharada, + UNICODE_SCRIPT_Shavian, + UNICODE_SCRIPT_Siddham, + UNICODE_SCRIPT_SignWriting, + UNICODE_SCRIPT_Sinhala, + UNICODE_SCRIPT_Sogdian, + UNICODE_SCRIPT_Sora_Sompeng, + UNICODE_SCRIPT_Soyombo, + UNICODE_SCRIPT_Sundanese, + UNICODE_SCRIPT_Syloti_Nagri, + UNICODE_SCRIPT_Syriac, + UNICODE_SCRIPT_Tagalog, + UNICODE_SCRIPT_Tagbanwa, + UNICODE_SCRIPT_Tai_Le, + UNICODE_SCRIPT_Tai_Tham, + UNICODE_SCRIPT_Tai_Viet, + UNICODE_SCRIPT_Takri, + UNICODE_SCRIPT_Tamil, + UNICODE_SCRIPT_Tangut, + UNICODE_SCRIPT_Telugu, + UNICODE_SCRIPT_Thaana, + UNICODE_SCRIPT_Thai, + UNICODE_SCRIPT_Tibetan, + UNICODE_SCRIPT_Tifinagh, + UNICODE_SCRIPT_Tirhuta, + UNICODE_SCRIPT_Tangsa, + UNICODE_SCRIPT_Toto, + UNICODE_SCRIPT_Ugaritic, + UNICODE_SCRIPT_Vai, + UNICODE_SCRIPT_Vithkuqi, + UNICODE_SCRIPT_Wancho, + UNICODE_SCRIPT_Warang_Citi, + UNICODE_SCRIPT_Yezidi, + UNICODE_SCRIPT_Yi, + UNICODE_SCRIPT_Zanabazar_Square, + UNICODE_SCRIPT_COUNT, +} UnicodeScriptEnum; + +static const char unicode_script_name_table[] = + "Adlam,Adlm" "\0" + "Ahom,Ahom" "\0" + "Anatolian_Hieroglyphs,Hluw" "\0" + "Arabic,Arab" "\0" + "Armenian,Armn" "\0" + "Avestan,Avst" "\0" + "Balinese,Bali" "\0" + "Bamum,Bamu" "\0" + "Bassa_Vah,Bass" "\0" + "Batak,Batk" "\0" + "Bengali,Beng" "\0" + "Bhaiksuki,Bhks" "\0" + "Bopomofo,Bopo" "\0" + "Brahmi,Brah" "\0" + "Braille,Brai" "\0" + "Buginese,Bugi" "\0" + "Buhid,Buhd" "\0" + "Canadian_Aboriginal,Cans" "\0" + "Carian,Cari" "\0" + "Caucasian_Albanian,Aghb" "\0" + "Chakma,Cakm" "\0" + "Cham,Cham" "\0" + "Cherokee,Cher" "\0" + "Chorasmian,Chrs" "\0" + "Common,Zyyy" "\0" + "Coptic,Copt,Qaac" "\0" + "Cuneiform,Xsux" "\0" + "Cypriot,Cprt" "\0" + "Cyrillic,Cyrl" "\0" + "Cypro_Minoan,Cpmn" "\0" + "Deseret,Dsrt" "\0" + "Devanagari,Deva" "\0" + "Dives_Akuru,Diak" "\0" + "Dogra,Dogr" "\0" + "Duployan,Dupl" "\0" + "Egyptian_Hieroglyphs,Egyp" "\0" + "Elbasan,Elba" "\0" + "Elymaic,Elym" "\0" + "Ethiopic,Ethi" "\0" + "Georgian,Geor" "\0" + "Glagolitic,Glag" "\0" + "Gothic,Goth" "\0" + "Grantha,Gran" "\0" + "Greek,Grek" "\0" + "Gujarati,Gujr" "\0" + "Gunjala_Gondi,Gong" "\0" + "Gurmukhi,Guru" "\0" + "Han,Hani" "\0" + "Hangul,Hang" "\0" + "Hanifi_Rohingya,Rohg" "\0" + "Hanunoo,Hano" "\0" + "Hatran,Hatr" "\0" + "Hebrew,Hebr" "\0" + "Hiragana,Hira" "\0" + "Imperial_Aramaic,Armi" "\0" + "Inherited,Zinh,Qaai" "\0" + "Inscriptional_Pahlavi,Phli" "\0" + "Inscriptional_Parthian,Prti" "\0" + "Javanese,Java" "\0" + "Kaithi,Kthi" "\0" + "Kannada,Knda" "\0" + "Katakana,Kana" "\0" + "Kayah_Li,Kali" "\0" + "Kharoshthi,Khar" "\0" + "Khmer,Khmr" "\0" + "Khojki,Khoj" "\0" + "Khitan_Small_Script,Kits" "\0" + "Khudawadi,Sind" "\0" + "Lao,Laoo" "\0" + "Latin,Latn" "\0" + "Lepcha,Lepc" "\0" + "Limbu,Limb" "\0" + "Linear_A,Lina" "\0" + "Linear_B,Linb" "\0" + "Lisu,Lisu" "\0" + "Lycian,Lyci" "\0" + "Lydian,Lydi" "\0" + "Makasar,Maka" "\0" + "Mahajani,Mahj" "\0" + "Malayalam,Mlym" "\0" + "Mandaic,Mand" "\0" + "Manichaean,Mani" "\0" + "Marchen,Marc" "\0" + "Masaram_Gondi,Gonm" "\0" + "Medefaidrin,Medf" "\0" + "Meetei_Mayek,Mtei" "\0" + "Mende_Kikakui,Mend" "\0" + "Meroitic_Cursive,Merc" "\0" + "Meroitic_Hieroglyphs,Mero" "\0" + "Miao,Plrd" "\0" + "Modi,Modi" "\0" + "Mongolian,Mong" "\0" + "Mro,Mroo" "\0" + "Multani,Mult" "\0" + "Myanmar,Mymr" "\0" + "Nabataean,Nbat" "\0" + "Nandinagari,Nand" "\0" + "New_Tai_Lue,Talu" "\0" + "Newa,Newa" "\0" + "Nko,Nkoo" "\0" + "Nushu,Nshu" "\0" + "Nyiakeng_Puachue_Hmong,Hmnp" "\0" + "Ogham,Ogam" "\0" + "Ol_Chiki,Olck" "\0" + "Old_Hungarian,Hung" "\0" + "Old_Italic,Ital" "\0" + "Old_North_Arabian,Narb" "\0" + "Old_Permic,Perm" "\0" + "Old_Persian,Xpeo" "\0" + "Old_Sogdian,Sogo" "\0" + "Old_South_Arabian,Sarb" "\0" + "Old_Turkic,Orkh" "\0" + "Old_Uyghur,Ougr" "\0" + "Oriya,Orya" "\0" + "Osage,Osge" "\0" + "Osmanya,Osma" "\0" + "Pahawh_Hmong,Hmng" "\0" + "Palmyrene,Palm" "\0" + "Pau_Cin_Hau,Pauc" "\0" + "Phags_Pa,Phag" "\0" + "Phoenician,Phnx" "\0" + "Psalter_Pahlavi,Phlp" "\0" + "Rejang,Rjng" "\0" + "Runic,Runr" "\0" + "Samaritan,Samr" "\0" + "Saurashtra,Saur" "\0" + "Sharada,Shrd" "\0" + "Shavian,Shaw" "\0" + "Siddham,Sidd" "\0" + "SignWriting,Sgnw" "\0" + "Sinhala,Sinh" "\0" + "Sogdian,Sogd" "\0" + "Sora_Sompeng,Sora" "\0" + "Soyombo,Soyo" "\0" + "Sundanese,Sund" "\0" + "Syloti_Nagri,Sylo" "\0" + "Syriac,Syrc" "\0" + "Tagalog,Tglg" "\0" + "Tagbanwa,Tagb" "\0" + "Tai_Le,Tale" "\0" + "Tai_Tham,Lana" "\0" + "Tai_Viet,Tavt" "\0" + "Takri,Takr" "\0" + "Tamil,Taml" "\0" + "Tangut,Tang" "\0" + "Telugu,Telu" "\0" + "Thaana,Thaa" "\0" + "Thai,Thai" "\0" + "Tibetan,Tibt" "\0" + "Tifinagh,Tfng" "\0" + "Tirhuta,Tirh" "\0" + "Tangsa,Tnsa" "\0" + "Toto,Toto" "\0" + "Ugaritic,Ugar" "\0" + "Vai,Vaii" "\0" + "Vithkuqi,Vith" "\0" + "Wancho,Wcho" "\0" + "Warang_Citi,Wara" "\0" + "Yezidi,Yezi" "\0" + "Yi,Yiii" "\0" + "Zanabazar_Square,Zanb" "\0" +; + +static const uint8_t unicode_script_table[2690] = { + 0xc0, 0x19, 0x99, 0x46, 0x85, 0x19, 0x99, 0x46, + 0xae, 0x19, 0x80, 0x46, 0x8e, 0x19, 0x80, 0x46, + 0x84, 0x19, 0x96, 0x46, 0x80, 0x19, 0x9e, 0x46, + 0x80, 0x19, 0xe1, 0x60, 0x46, 0xa6, 0x19, 0x84, + 0x46, 0x84, 0x19, 0x81, 0x0d, 0x93, 0x19, 0xe0, + 0x0f, 0x38, 0x83, 0x2c, 0x80, 0x19, 0x82, 0x2c, + 0x01, 0x83, 0x2c, 0x80, 0x19, 0x80, 0x2c, 0x03, + 0x80, 0x2c, 0x80, 0x19, 0x80, 0x2c, 0x80, 0x19, + 0x82, 0x2c, 0x00, 0x80, 0x2c, 0x00, 0x93, 0x2c, + 0x00, 0xbe, 0x2c, 0x8d, 0x1a, 0x8f, 0x2c, 0xe0, + 0x24, 0x1d, 0x81, 0x38, 0xe0, 0x48, 0x1d, 0x00, + 0xa5, 0x05, 0x01, 0xb1, 0x05, 0x01, 0x82, 0x05, + 0x00, 0xb6, 0x35, 0x07, 0x9a, 0x35, 0x03, 0x85, + 0x35, 0x0a, 0x84, 0x04, 0x80, 0x19, 0x85, 0x04, + 0x80, 0x19, 0x8d, 0x04, 0x80, 0x19, 0x82, 0x04, + 0x80, 0x19, 0x9f, 0x04, 0x80, 0x19, 0x89, 0x04, + 0x8a, 0x38, 0x99, 0x04, 0x80, 0x38, 0xe0, 0x0b, + 0x04, 0x80, 0x19, 0xa1, 0x04, 0x8d, 0x89, 0x00, + 0xbb, 0x89, 0x01, 0x82, 0x89, 0xaf, 0x04, 0xb1, + 0x93, 0x0d, 0xba, 0x64, 0x01, 0x82, 0x64, 0xad, + 0x7d, 0x01, 0x8e, 0x7d, 0x00, 0x9b, 0x51, 0x01, + 0x80, 0x51, 0x00, 0x8a, 0x89, 0x04, 0x9e, 0x04, + 0x00, 0x81, 0x04, 0x05, 0xc9, 0x04, 0x80, 0x19, + 0x9c, 0x04, 0xd0, 0x20, 0x83, 0x38, 0x8e, 0x20, + 0x81, 0x19, 0x99, 0x20, 0x83, 0x0b, 0x00, 0x87, + 0x0b, 0x01, 0x81, 0x0b, 0x01, 0x95, 0x0b, 0x00, + 0x86, 0x0b, 0x00, 0x80, 0x0b, 0x02, 0x83, 0x0b, + 0x01, 0x88, 0x0b, 0x01, 0x81, 0x0b, 0x01, 0x83, + 0x0b, 0x07, 0x80, 0x0b, 0x03, 0x81, 0x0b, 0x00, + 0x84, 0x0b, 0x01, 0x98, 0x0b, 0x01, 0x82, 0x2f, + 0x00, 0x85, 0x2f, 0x03, 0x81, 0x2f, 0x01, 0x95, + 0x2f, 0x00, 0x86, 0x2f, 0x00, 0x81, 0x2f, 0x00, + 0x81, 0x2f, 0x00, 0x81, 0x2f, 0x01, 0x80, 0x2f, + 0x00, 0x84, 0x2f, 0x03, 0x81, 0x2f, 0x01, 0x82, + 0x2f, 0x02, 0x80, 0x2f, 0x06, 0x83, 0x2f, 0x00, + 0x80, 0x2f, 0x06, 0x90, 0x2f, 0x09, 0x82, 0x2d, + 0x00, 0x88, 0x2d, 0x00, 0x82, 0x2d, 0x00, 0x95, + 0x2d, 0x00, 0x86, 0x2d, 0x00, 0x81, 0x2d, 0x00, + 0x84, 0x2d, 0x01, 0x89, 0x2d, 0x00, 0x82, 0x2d, + 0x00, 0x82, 0x2d, 0x01, 0x80, 0x2d, 0x0e, 0x83, + 0x2d, 0x01, 0x8b, 0x2d, 0x06, 0x86, 0x2d, 0x00, + 0x82, 0x72, 0x00, 0x87, 0x72, 0x01, 0x81, 0x72, + 0x01, 0x95, 0x72, 0x00, 0x86, 0x72, 0x00, 0x81, + 0x72, 0x00, 0x84, 0x72, 0x01, 0x88, 0x72, 0x01, + 0x81, 0x72, 0x01, 0x82, 0x72, 0x06, 0x82, 0x72, + 0x03, 0x81, 0x72, 0x00, 0x84, 0x72, 0x01, 0x91, + 0x72, 0x09, 0x81, 0x90, 0x00, 0x85, 0x90, 0x02, + 0x82, 0x90, 0x00, 0x83, 0x90, 0x02, 0x81, 0x90, + 0x00, 0x80, 0x90, 0x00, 0x81, 0x90, 0x02, 0x81, + 0x90, 0x02, 0x82, 0x90, 0x02, 0x8b, 0x90, 0x03, + 0x84, 0x90, 0x02, 0x82, 0x90, 0x00, 0x83, 0x90, + 0x01, 0x80, 0x90, 0x05, 0x80, 0x90, 0x0d, 0x94, + 0x90, 0x04, 0x8c, 0x92, 0x00, 0x82, 0x92, 0x00, + 0x96, 0x92, 0x00, 0x8f, 0x92, 0x01, 0x88, 0x92, + 0x00, 0x82, 0x92, 0x00, 0x83, 0x92, 0x06, 0x81, + 0x92, 0x00, 0x82, 0x92, 0x01, 0x80, 0x92, 0x01, + 0x83, 0x92, 0x01, 0x89, 0x92, 0x06, 0x88, 0x92, + 0x8c, 0x3d, 0x00, 0x82, 0x3d, 0x00, 0x96, 0x3d, + 0x00, 0x89, 0x3d, 0x00, 0x84, 0x3d, 0x01, 0x88, + 0x3d, 0x00, 0x82, 0x3d, 0x00, 0x83, 0x3d, 0x06, + 0x81, 0x3d, 0x05, 0x81, 0x3d, 0x00, 0x83, 0x3d, + 0x01, 0x89, 0x3d, 0x00, 0x81, 0x3d, 0x0c, 0x8c, + 0x50, 0x00, 0x82, 0x50, 0x00, 0xb2, 0x50, 0x00, + 0x82, 0x50, 0x00, 0x85, 0x50, 0x03, 0x8f, 0x50, + 0x01, 0x99, 0x50, 0x00, 0x82, 0x83, 0x00, 0x91, + 0x83, 0x02, 0x97, 0x83, 0x00, 0x88, 0x83, 0x00, + 0x80, 0x83, 0x01, 0x86, 0x83, 0x02, 0x80, 0x83, + 0x03, 0x85, 0x83, 0x00, 0x80, 0x83, 0x00, 0x87, + 0x83, 0x05, 0x89, 0x83, 0x01, 0x82, 0x83, 0x0b, + 0xb9, 0x94, 0x03, 0x80, 0x19, 0x9b, 0x94, 0x24, + 0x81, 0x45, 0x00, 0x80, 0x45, 0x00, 0x84, 0x45, + 0x00, 0x97, 0x45, 0x00, 0x80, 0x45, 0x00, 0x96, + 0x45, 0x01, 0x84, 0x45, 0x00, 0x80, 0x45, 0x00, + 0x85, 0x45, 0x01, 0x89, 0x45, 0x01, 0x83, 0x45, + 0x1f, 0xc7, 0x95, 0x00, 0xa3, 0x95, 0x03, 0xa6, + 0x95, 0x00, 0xa3, 0x95, 0x00, 0x8e, 0x95, 0x00, + 0x86, 0x95, 0x83, 0x19, 0x81, 0x95, 0x24, 0xe0, + 0x3f, 0x5f, 0xa5, 0x28, 0x00, 0x80, 0x28, 0x04, + 0x80, 0x28, 0x01, 0xaa, 0x28, 0x80, 0x19, 0x83, + 0x28, 0xe0, 0x9f, 0x31, 0xc8, 0x27, 0x00, 0x83, + 0x27, 0x01, 0x86, 0x27, 0x00, 0x80, 0x27, 0x00, + 0x83, 0x27, 0x01, 0xa8, 0x27, 0x00, 0x83, 0x27, + 0x01, 0xa0, 0x27, 0x00, 0x83, 0x27, 0x01, 0x86, + 0x27, 0x00, 0x80, 0x27, 0x00, 0x83, 0x27, 0x01, + 0x8e, 0x27, 0x00, 0xb8, 0x27, 0x00, 0x83, 0x27, + 0x01, 0xc2, 0x27, 0x01, 0x9f, 0x27, 0x02, 0x99, + 0x27, 0x05, 0xd5, 0x17, 0x01, 0x85, 0x17, 0x01, + 0xe2, 0x1f, 0x12, 0x9c, 0x67, 0x02, 0xca, 0x7c, + 0x82, 0x19, 0x8a, 0x7c, 0x06, 0x95, 0x8a, 0x08, + 0x80, 0x8a, 0x94, 0x33, 0x81, 0x19, 0x08, 0x93, + 0x11, 0x0b, 0x8c, 0x8b, 0x00, 0x82, 0x8b, 0x00, + 0x81, 0x8b, 0x0b, 0xdd, 0x41, 0x01, 0x89, 0x41, + 0x05, 0x89, 0x41, 0x05, 0x81, 0x5c, 0x81, 0x19, + 0x80, 0x5c, 0x80, 0x19, 0x93, 0x5c, 0x05, 0xd8, + 0x5c, 0x06, 0xaa, 0x5c, 0x04, 0xc5, 0x12, 0x09, + 0x9e, 0x48, 0x00, 0x8b, 0x48, 0x03, 0x8b, 0x48, + 0x03, 0x80, 0x48, 0x02, 0x8b, 0x48, 0x9d, 0x8c, + 0x01, 0x84, 0x8c, 0x0a, 0xab, 0x62, 0x03, 0x99, + 0x62, 0x05, 0x8a, 0x62, 0x02, 0x81, 0x62, 0x9f, + 0x41, 0x9b, 0x10, 0x01, 0x81, 0x10, 0xbe, 0x8d, + 0x00, 0x9c, 0x8d, 0x01, 0x8a, 0x8d, 0x05, 0x89, + 0x8d, 0x05, 0x8d, 0x8d, 0x01, 0x9e, 0x38, 0x30, + 0xcc, 0x07, 0x02, 0xae, 0x07, 0x00, 0xbf, 0x87, + 0xb3, 0x0a, 0x07, 0x83, 0x0a, 0xb7, 0x47, 0x02, + 0x8e, 0x47, 0x02, 0x82, 0x47, 0xaf, 0x68, 0x88, + 0x1d, 0x06, 0xaa, 0x28, 0x01, 0x82, 0x28, 0x87, + 0x87, 0x07, 0x82, 0x38, 0x80, 0x19, 0x8c, 0x38, + 0x80, 0x19, 0x86, 0x38, 0x83, 0x19, 0x80, 0x38, + 0x85, 0x19, 0x80, 0x38, 0x82, 0x19, 0x81, 0x38, + 0x80, 0x19, 0x04, 0xa5, 0x46, 0x84, 0x2c, 0x80, + 0x1d, 0xb0, 0x46, 0x84, 0x2c, 0x83, 0x46, 0x84, + 0x2c, 0x8c, 0x46, 0x80, 0x1d, 0xc5, 0x46, 0x80, + 0x2c, 0xbf, 0x38, 0xe0, 0x9f, 0x46, 0x95, 0x2c, + 0x01, 0x85, 0x2c, 0x01, 0xa5, 0x2c, 0x01, 0x85, + 0x2c, 0x01, 0x87, 0x2c, 0x00, 0x80, 0x2c, 0x00, + 0x80, 0x2c, 0x00, 0x80, 0x2c, 0x00, 0x9e, 0x2c, + 0x01, 0xb4, 0x2c, 0x00, 0x8e, 0x2c, 0x00, 0x8d, + 0x2c, 0x01, 0x85, 0x2c, 0x00, 0x92, 0x2c, 0x01, + 0x82, 0x2c, 0x00, 0x88, 0x2c, 0x00, 0x8b, 0x19, + 0x81, 0x38, 0xd6, 0x19, 0x00, 0x8a, 0x19, 0x80, + 0x46, 0x01, 0x8a, 0x19, 0x80, 0x46, 0x8e, 0x19, + 0x00, 0x8c, 0x46, 0x02, 0xa0, 0x19, 0x0e, 0xa0, + 0x38, 0x0e, 0xa5, 0x19, 0x80, 0x2c, 0x82, 0x19, + 0x81, 0x46, 0x85, 0x19, 0x80, 0x46, 0x9a, 0x19, + 0x80, 0x46, 0x90, 0x19, 0xa8, 0x46, 0x82, 0x19, + 0x03, 0xe2, 0x36, 0x19, 0x18, 0x8a, 0x19, 0x14, + 0xe3, 0x3f, 0x19, 0xe0, 0x9f, 0x0f, 0xe2, 0x13, + 0x19, 0x01, 0x9f, 0x19, 0x00, 0xe0, 0x08, 0x19, + 0xdf, 0x29, 0x9f, 0x46, 0xe0, 0x13, 0x1a, 0x04, + 0x86, 0x1a, 0xa5, 0x28, 0x00, 0x80, 0x28, 0x04, + 0x80, 0x28, 0x01, 0xb7, 0x96, 0x06, 0x81, 0x96, + 0x0d, 0x80, 0x96, 0x96, 0x27, 0x08, 0x86, 0x27, + 0x00, 0x86, 0x27, 0x00, 0x86, 0x27, 0x00, 0x86, + 0x27, 0x00, 0x86, 0x27, 0x00, 0x86, 0x27, 0x00, + 0x86, 0x27, 0x00, 0x86, 0x27, 0x00, 0x9f, 0x1d, + 0xdd, 0x19, 0x21, 0x99, 0x30, 0x00, 0xd8, 0x30, + 0x0b, 0xe0, 0x75, 0x30, 0x19, 0x8b, 0x19, 0x03, + 0x84, 0x19, 0x80, 0x30, 0x80, 0x19, 0x80, 0x30, + 0x98, 0x19, 0x88, 0x30, 0x83, 0x38, 0x81, 0x31, + 0x87, 0x19, 0x83, 0x30, 0x83, 0x19, 0x00, 0xd5, + 0x36, 0x01, 0x81, 0x38, 0x81, 0x19, 0x82, 0x36, + 0x80, 0x19, 0xd9, 0x3e, 0x81, 0x19, 0x82, 0x3e, + 0x04, 0xaa, 0x0d, 0x00, 0xdd, 0x31, 0x00, 0x8f, + 0x19, 0x9f, 0x0d, 0xa3, 0x19, 0x0b, 0x8f, 0x3e, + 0x9e, 0x31, 0x00, 0xbf, 0x19, 0x9e, 0x31, 0xd0, + 0x19, 0xae, 0x3e, 0x80, 0x19, 0xd7, 0x3e, 0xe0, + 0x47, 0x19, 0xf0, 0x09, 0x5f, 0x30, 0xbf, 0x19, + 0xf0, 0x41, 0x9f, 0x30, 0xe4, 0x2c, 0xa0, 0x02, + 0xb6, 0xa0, 0x08, 0xaf, 0x4b, 0xe0, 0xcb, 0x9b, + 0x13, 0xdf, 0x1d, 0xd7, 0x08, 0x07, 0xa1, 0x19, + 0xe0, 0x05, 0x46, 0x82, 0x19, 0xbf, 0x46, 0x04, + 0x81, 0x46, 0x00, 0x80, 0x46, 0x00, 0x84, 0x46, + 0x17, 0x8d, 0x46, 0xac, 0x88, 0x02, 0x89, 0x19, + 0x05, 0xb7, 0x78, 0x07, 0xc5, 0x7e, 0x07, 0x8b, + 0x7e, 0x05, 0x9f, 0x20, 0xad, 0x3f, 0x80, 0x19, + 0x80, 0x3f, 0xa3, 0x7b, 0x0a, 0x80, 0x7b, 0x9c, + 0x31, 0x02, 0xcd, 0x3b, 0x00, 0x80, 0x19, 0x89, + 0x3b, 0x03, 0x81, 0x3b, 0x9e, 0x5f, 0x00, 0xb6, + 0x16, 0x08, 0x8d, 0x16, 0x01, 0x89, 0x16, 0x01, + 0x83, 0x16, 0x9f, 0x5f, 0xc2, 0x8e, 0x17, 0x84, + 0x8e, 0x96, 0x56, 0x09, 0x85, 0x27, 0x01, 0x85, + 0x27, 0x01, 0x85, 0x27, 0x08, 0x86, 0x27, 0x00, + 0x86, 0x27, 0x00, 0xaa, 0x46, 0x80, 0x19, 0x88, + 0x46, 0x80, 0x2c, 0x83, 0x46, 0x81, 0x19, 0x03, + 0xcf, 0x17, 0xad, 0x56, 0x01, 0x89, 0x56, 0x05, + 0xf0, 0x1b, 0x43, 0x31, 0x0b, 0x96, 0x31, 0x03, + 0xb0, 0x31, 0x70, 0x10, 0xa3, 0xe1, 0x0d, 0x30, + 0x01, 0xe0, 0x09, 0x30, 0x25, 0x86, 0x46, 0x0b, + 0x84, 0x05, 0x04, 0x99, 0x35, 0x00, 0x84, 0x35, + 0x00, 0x80, 0x35, 0x00, 0x81, 0x35, 0x00, 0x81, + 0x35, 0x00, 0x89, 0x35, 0xe0, 0x12, 0x04, 0x0f, + 0xe1, 0x0a, 0x04, 0x81, 0x19, 0xcf, 0x04, 0x01, + 0xb5, 0x04, 0x06, 0x80, 0x04, 0x1f, 0x8f, 0x04, + 0x8f, 0x38, 0x89, 0x19, 0x05, 0x8d, 0x38, 0x81, + 0x1d, 0xa2, 0x19, 0x00, 0x92, 0x19, 0x00, 0x83, + 0x19, 0x03, 0x84, 0x04, 0x00, 0xe0, 0x26, 0x04, + 0x01, 0x80, 0x19, 0x00, 0x9f, 0x19, 0x99, 0x46, + 0x85, 0x19, 0x99, 0x46, 0x8a, 0x19, 0x89, 0x3e, + 0x80, 0x19, 0xac, 0x3e, 0x81, 0x19, 0x9e, 0x31, + 0x02, 0x85, 0x31, 0x01, 0x85, 0x31, 0x01, 0x85, + 0x31, 0x01, 0x82, 0x31, 0x02, 0x86, 0x19, 0x00, + 0x86, 0x19, 0x09, 0x84, 0x19, 0x01, 0x8b, 0x4a, + 0x00, 0x99, 0x4a, 0x00, 0x92, 0x4a, 0x00, 0x81, + 0x4a, 0x00, 0x8e, 0x4a, 0x01, 0x8d, 0x4a, 0x21, + 0xe0, 0x1a, 0x4a, 0x04, 0x82, 0x19, 0x03, 0xac, + 0x19, 0x02, 0x88, 0x19, 0xce, 0x2c, 0x00, 0x8c, + 0x19, 0x02, 0x80, 0x2c, 0x2e, 0xac, 0x19, 0x80, + 0x38, 0x60, 0x21, 0x9c, 0x4c, 0x02, 0xb0, 0x13, + 0x0e, 0x80, 0x38, 0x9a, 0x19, 0x03, 0xa3, 0x6a, + 0x08, 0x82, 0x6a, 0x9a, 0x2a, 0x04, 0xaa, 0x6c, + 0x04, 0x9d, 0x9a, 0x00, 0x80, 0x9a, 0xa3, 0x6d, + 0x03, 0x8d, 0x6d, 0x29, 0xcf, 0x1f, 0xaf, 0x80, + 0x9d, 0x74, 0x01, 0x89, 0x74, 0x05, 0xa3, 0x73, + 0x03, 0xa3, 0x73, 0x03, 0xa7, 0x25, 0x07, 0xb3, + 0x14, 0x0a, 0x80, 0x14, 0x8a, 0x9c, 0x00, 0x8e, + 0x9c, 0x00, 0x86, 0x9c, 0x00, 0x81, 0x9c, 0x00, + 0x8a, 0x9c, 0x00, 0x8e, 0x9c, 0x00, 0x86, 0x9c, + 0x00, 0x81, 0x9c, 0x42, 0xe0, 0xd6, 0x49, 0x08, + 0x95, 0x49, 0x09, 0x87, 0x49, 0x17, 0x85, 0x46, + 0x00, 0xa9, 0x46, 0x00, 0x88, 0x46, 0x44, 0x85, + 0x1c, 0x01, 0x80, 0x1c, 0x00, 0xab, 0x1c, 0x00, + 0x81, 0x1c, 0x02, 0x80, 0x1c, 0x01, 0x80, 0x1c, + 0x95, 0x37, 0x00, 0x88, 0x37, 0x9f, 0x76, 0x9e, + 0x60, 0x07, 0x88, 0x60, 0x2f, 0x92, 0x34, 0x00, + 0x81, 0x34, 0x04, 0x84, 0x34, 0x9b, 0x79, 0x02, + 0x80, 0x79, 0x99, 0x4d, 0x04, 0x80, 0x4d, 0x3f, + 0x9f, 0x59, 0x97, 0x58, 0x03, 0x93, 0x58, 0x01, + 0xad, 0x58, 0x83, 0x40, 0x00, 0x81, 0x40, 0x04, + 0x87, 0x40, 0x00, 0x82, 0x40, 0x00, 0x9c, 0x40, + 0x01, 0x82, 0x40, 0x03, 0x89, 0x40, 0x06, 0x88, + 0x40, 0x06, 0x9f, 0x6f, 0x9f, 0x6b, 0x1f, 0xa6, + 0x52, 0x03, 0x8b, 0x52, 0x08, 0xb5, 0x06, 0x02, + 0x86, 0x06, 0x95, 0x3a, 0x01, 0x87, 0x3a, 0x92, + 0x39, 0x04, 0x87, 0x39, 0x91, 0x7a, 0x06, 0x83, + 0x7a, 0x0b, 0x86, 0x7a, 0x4f, 0xc8, 0x70, 0x36, + 0xb2, 0x69, 0x0c, 0xb2, 0x69, 0x06, 0x85, 0x69, + 0xa7, 0x32, 0x07, 0x89, 0x32, 0x60, 0xc5, 0x9e, + 0x04, 0x00, 0xa9, 0x9f, 0x00, 0x82, 0x9f, 0x01, + 0x81, 0x9f, 0x4d, 0xa7, 0x6e, 0x07, 0xa9, 0x84, + 0x15, 0x99, 0x71, 0x25, 0x9b, 0x18, 0x13, 0x96, + 0x26, 0x08, 0xcd, 0x0e, 0x03, 0xa3, 0x0e, 0x08, + 0x80, 0x0e, 0xc2, 0x3c, 0x09, 0x80, 0x3c, 0x01, + 0x98, 0x85, 0x06, 0x89, 0x85, 0x05, 0xb4, 0x15, + 0x00, 0x91, 0x15, 0x07, 0xa6, 0x4f, 0x08, 0xdf, + 0x7f, 0x00, 0x93, 0x83, 0x0a, 0x91, 0x42, 0x00, + 0xab, 0x42, 0x40, 0x86, 0x5e, 0x00, 0x80, 0x5e, + 0x00, 0x83, 0x5e, 0x00, 0x8e, 0x5e, 0x00, 0x8a, + 0x5e, 0x05, 0xba, 0x44, 0x04, 0x89, 0x44, 0x05, + 0x83, 0x2b, 0x00, 0x87, 0x2b, 0x01, 0x81, 0x2b, + 0x01, 0x95, 0x2b, 0x00, 0x86, 0x2b, 0x00, 0x81, + 0x2b, 0x00, 0x84, 0x2b, 0x00, 0x80, 0x38, 0x88, + 0x2b, 0x01, 0x81, 0x2b, 0x01, 0x82, 0x2b, 0x01, + 0x80, 0x2b, 0x05, 0x80, 0x2b, 0x04, 0x86, 0x2b, + 0x01, 0x86, 0x2b, 0x02, 0x84, 0x2b, 0x60, 0x2a, + 0xdb, 0x63, 0x00, 0x84, 0x63, 0x1d, 0xc7, 0x97, + 0x07, 0x89, 0x97, 0x60, 0x45, 0xb5, 0x81, 0x01, + 0xa5, 0x81, 0x21, 0xc4, 0x5b, 0x0a, 0x89, 0x5b, + 0x05, 0x8c, 0x5c, 0x12, 0xb9, 0x8f, 0x05, 0x89, + 0x8f, 0x35, 0x9a, 0x02, 0x01, 0x8e, 0x02, 0x03, + 0x96, 0x02, 0x60, 0x58, 0xbb, 0x22, 0x60, 0x03, + 0xd2, 0x9e, 0x0b, 0x80, 0x9e, 0x86, 0x21, 0x01, + 0x80, 0x21, 0x01, 0x87, 0x21, 0x00, 0x81, 0x21, + 0x00, 0x9d, 0x21, 0x00, 0x81, 0x21, 0x01, 0x8b, + 0x21, 0x08, 0x89, 0x21, 0x45, 0x87, 0x61, 0x01, + 0xad, 0x61, 0x01, 0x8a, 0x61, 0x1a, 0xc7, 0xa1, + 0x07, 0xd2, 0x86, 0x0c, 0x8f, 0x12, 0xb8, 0x77, + 0x60, 0xa6, 0x88, 0x0c, 0x00, 0xac, 0x0c, 0x00, + 0x8d, 0x0c, 0x09, 0x9c, 0x0c, 0x02, 0x9f, 0x53, + 0x01, 0x95, 0x53, 0x00, 0x8d, 0x53, 0x48, 0x86, + 0x54, 0x00, 0x81, 0x54, 0x00, 0xab, 0x54, 0x02, + 0x80, 0x54, 0x00, 0x81, 0x54, 0x00, 0x88, 0x54, + 0x07, 0x89, 0x54, 0x05, 0x85, 0x2e, 0x00, 0x81, + 0x2e, 0x00, 0xa4, 0x2e, 0x00, 0x81, 0x2e, 0x00, + 0x85, 0x2e, 0x06, 0x89, 0x2e, 0x60, 0xd5, 0x98, + 0x4e, 0x60, 0x56, 0x80, 0x4b, 0x0e, 0xb1, 0x90, + 0x0c, 0x80, 0x90, 0xe3, 0x39, 0x1b, 0x60, 0x05, + 0xe0, 0x0e, 0x1b, 0x00, 0x84, 0x1b, 0x0a, 0xe0, + 0x63, 0x1b, 0x69, 0xeb, 0xe0, 0x02, 0x1e, 0x0c, + 0xe3, 0xce, 0x24, 0x00, 0x88, 0x24, 0x6f, 0x66, + 0xe1, 0xe6, 0x03, 0x70, 0x11, 0x58, 0xe1, 0xd8, + 0x08, 0x06, 0x9e, 0x5d, 0x00, 0x89, 0x5d, 0x03, + 0x81, 0x5d, 0xce, 0x98, 0x00, 0x89, 0x98, 0x05, + 0x9d, 0x09, 0x01, 0x85, 0x09, 0x09, 0xc5, 0x75, + 0x09, 0x89, 0x75, 0x00, 0x86, 0x75, 0x00, 0x94, + 0x75, 0x04, 0x92, 0x75, 0x62, 0x4f, 0xda, 0x55, + 0x60, 0x04, 0xca, 0x5a, 0x03, 0xb8, 0x5a, 0x06, + 0x90, 0x5a, 0x3f, 0x80, 0x91, 0x80, 0x65, 0x81, + 0x30, 0x80, 0x43, 0x0a, 0x81, 0x30, 0x0d, 0xf0, + 0x07, 0x97, 0x91, 0x07, 0xe2, 0x9f, 0x91, 0xe1, + 0x75, 0x43, 0x29, 0x88, 0x91, 0x70, 0x12, 0x86, + 0x83, 0x3e, 0x00, 0x86, 0x3e, 0x00, 0x81, 0x3e, + 0x00, 0x80, 0x3e, 0xe0, 0xbe, 0x36, 0x82, 0x3e, + 0x2c, 0x82, 0x36, 0x10, 0x83, 0x3e, 0x07, 0xe1, + 0x2b, 0x65, 0x68, 0xa3, 0xe0, 0x0a, 0x23, 0x04, + 0x8c, 0x23, 0x02, 0x88, 0x23, 0x06, 0x89, 0x23, + 0x01, 0x83, 0x23, 0x83, 0x19, 0x70, 0x01, 0xfb, + 0xad, 0x38, 0x01, 0x96, 0x38, 0x08, 0xe0, 0x13, + 0x19, 0x3b, 0xe0, 0x95, 0x19, 0x09, 0xa6, 0x19, + 0x01, 0xbd, 0x19, 0x82, 0x38, 0x90, 0x19, 0x87, + 0x38, 0x81, 0x19, 0x86, 0x38, 0x9d, 0x19, 0x83, + 0x38, 0xbc, 0x19, 0x14, 0xc5, 0x2c, 0x60, 0x39, + 0x93, 0x19, 0x0b, 0xd6, 0x19, 0x08, 0x98, 0x19, + 0x60, 0x26, 0xd4, 0x19, 0x00, 0xc6, 0x19, 0x00, + 0x81, 0x19, 0x01, 0x80, 0x19, 0x01, 0x81, 0x19, + 0x01, 0x83, 0x19, 0x00, 0x8b, 0x19, 0x00, 0x80, + 0x19, 0x00, 0x86, 0x19, 0x00, 0xc0, 0x19, 0x00, + 0x83, 0x19, 0x01, 0x87, 0x19, 0x00, 0x86, 0x19, + 0x00, 0x9b, 0x19, 0x00, 0x83, 0x19, 0x00, 0x84, + 0x19, 0x00, 0x80, 0x19, 0x02, 0x86, 0x19, 0x00, + 0xe0, 0xf3, 0x19, 0x01, 0xe0, 0xc3, 0x19, 0x01, + 0xb1, 0x19, 0xe2, 0x2b, 0x82, 0x0e, 0x84, 0x82, + 0x00, 0x8e, 0x82, 0x63, 0xef, 0x9e, 0x46, 0x60, + 0x80, 0x86, 0x29, 0x00, 0x90, 0x29, 0x01, 0x86, + 0x29, 0x00, 0x81, 0x29, 0x00, 0x84, 0x29, 0x60, + 0x74, 0xac, 0x66, 0x02, 0x8d, 0x66, 0x01, 0x89, + 0x66, 0x03, 0x81, 0x66, 0x60, 0xdf, 0x9e, 0x99, + 0x10, 0xb9, 0x9d, 0x04, 0x80, 0x9d, 0x64, 0x7f, + 0x86, 0x27, 0x00, 0x83, 0x27, 0x00, 0x81, 0x27, + 0x00, 0x8e, 0x27, 0x00, 0xe0, 0x64, 0x57, 0x01, + 0x8f, 0x57, 0x28, 0xcb, 0x01, 0x03, 0x89, 0x01, + 0x03, 0x81, 0x01, 0x62, 0xb0, 0xc3, 0x19, 0x4b, + 0xbc, 0x19, 0x60, 0x61, 0x83, 0x04, 0x00, 0x9a, + 0x04, 0x00, 0x81, 0x04, 0x00, 0x80, 0x04, 0x01, + 0x80, 0x04, 0x00, 0x89, 0x04, 0x00, 0x83, 0x04, + 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x05, 0x80, + 0x04, 0x03, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, + 0x80, 0x04, 0x00, 0x82, 0x04, 0x00, 0x81, 0x04, + 0x00, 0x80, 0x04, 0x01, 0x80, 0x04, 0x00, 0x80, + 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, + 0x80, 0x04, 0x00, 0x81, 0x04, 0x00, 0x80, 0x04, + 0x01, 0x83, 0x04, 0x00, 0x86, 0x04, 0x00, 0x83, + 0x04, 0x00, 0x83, 0x04, 0x00, 0x80, 0x04, 0x00, + 0x89, 0x04, 0x00, 0x90, 0x04, 0x04, 0x82, 0x04, + 0x00, 0x84, 0x04, 0x00, 0x90, 0x04, 0x33, 0x81, + 0x04, 0x60, 0xad, 0xab, 0x19, 0x03, 0xe0, 0x03, + 0x19, 0x0b, 0x8e, 0x19, 0x01, 0x8e, 0x19, 0x00, + 0x8e, 0x19, 0x00, 0xa4, 0x19, 0x09, 0xe0, 0x4d, + 0x19, 0x37, 0x99, 0x19, 0x80, 0x36, 0x81, 0x19, + 0x0c, 0xab, 0x19, 0x03, 0x88, 0x19, 0x06, 0x81, + 0x19, 0x0d, 0x85, 0x19, 0x60, 0x39, 0xe3, 0x77, + 0x19, 0x04, 0x8f, 0x19, 0x02, 0x8c, 0x19, 0x02, + 0xe0, 0x13, 0x19, 0x0b, 0xd8, 0x19, 0x06, 0x8b, + 0x19, 0x03, 0x80, 0x19, 0x0e, 0x8b, 0x19, 0x03, + 0xb7, 0x19, 0x07, 0x89, 0x19, 0x05, 0xa7, 0x19, + 0x07, 0x9d, 0x19, 0x01, 0x81, 0x19, 0x4d, 0xe0, + 0xf3, 0x19, 0x0b, 0x8d, 0x19, 0x01, 0x84, 0x19, + 0x02, 0x84, 0x19, 0x02, 0x86, 0x19, 0x08, 0x9c, + 0x19, 0x02, 0x8a, 0x19, 0x04, 0x85, 0x19, 0x09, + 0x89, 0x19, 0x05, 0x87, 0x19, 0x07, 0x86, 0x19, + 0x08, 0xe0, 0x32, 0x19, 0x00, 0xb6, 0x19, 0x24, + 0x89, 0x19, 0x63, 0xa5, 0xf0, 0x96, 0x7f, 0x30, + 0x1f, 0xef, 0xd8, 0x30, 0x06, 0xe0, 0x7d, 0x30, + 0x01, 0xf0, 0x06, 0x21, 0x30, 0x0d, 0xf0, 0x0c, + 0xd0, 0x30, 0x6b, 0xbe, 0xe1, 0xbd, 0x30, 0x65, + 0x81, 0xf0, 0x02, 0xea, 0x30, 0x7a, 0xdc, 0x55, + 0x80, 0x19, 0x1d, 0xdf, 0x19, 0x60, 0x1f, 0xe0, + 0x8f, 0x38, +}; + +static const uint8_t unicode_script_ext_table[828] = { + 0x82, 0xc1, 0x00, 0x00, 0x01, 0x2c, 0x01, 0x00, + 0x00, 0x01, 0x2c, 0x1c, 0x00, 0x0c, 0x01, 0x46, + 0x80, 0x92, 0x00, 0x00, 0x02, 0x1d, 0x6c, 0x00, + 0x02, 0x1d, 0x29, 0x01, 0x02, 0x1d, 0x46, 0x00, + 0x02, 0x1d, 0x29, 0x81, 0x03, 0x00, 0x00, 0x06, + 0x04, 0x64, 0x32, 0x89, 0x93, 0x9f, 0x0d, 0x00, + 0x00, 0x06, 0x04, 0x64, 0x32, 0x89, 0x93, 0x9f, + 0x00, 0x03, 0x04, 0x89, 0x93, 0x01, 0x00, 0x00, + 0x07, 0x01, 0x04, 0x64, 0x32, 0x89, 0x93, 0x9f, + 0x1f, 0x00, 0x00, 0x09, 0x01, 0x04, 0x51, 0x52, + 0x71, 0x7a, 0x32, 0x84, 0x89, 0x09, 0x00, 0x0a, + 0x02, 0x04, 0x89, 0x09, 0x00, 0x09, 0x03, 0x04, + 0x93, 0x9f, 0x05, 0x00, 0x00, 0x02, 0x04, 0x89, + 0x62, 0x00, 0x00, 0x02, 0x04, 0x32, 0x81, 0xfb, + 0x00, 0x00, 0x0d, 0x0b, 0x20, 0x2b, 0x2d, 0x2f, + 0x3d, 0x46, 0x50, 0x72, 0x7f, 0x90, 0x92, 0x97, + 0x00, 0x0c, 0x0b, 0x20, 0x2b, 0x2d, 0x2f, 0x3d, + 0x46, 0x50, 0x72, 0x90, 0x92, 0x97, 0x10, 0x00, + 0x00, 0x14, 0x0b, 0x20, 0x22, 0x2e, 0x54, 0x2b, + 0x2d, 0x2f, 0x3d, 0x4f, 0x50, 0x61, 0x72, 0x44, + 0x83, 0x88, 0x8f, 0x90, 0x92, 0x97, 0x00, 0x15, + 0x0b, 0x20, 0x22, 0x2e, 0x54, 0x2b, 0x2d, 0x2f, + 0x3d, 0x48, 0x4f, 0x50, 0x61, 0x72, 0x44, 0x83, + 0x88, 0x8f, 0x90, 0x92, 0x97, 0x09, 0x04, 0x20, + 0x22, 0x3c, 0x4f, 0x75, 0x00, 0x09, 0x03, 0x0b, + 0x15, 0x88, 0x75, 0x00, 0x09, 0x02, 0x2f, 0x5e, + 0x75, 0x00, 0x09, 0x02, 0x2d, 0x42, 0x80, 0x75, + 0x00, 0x0d, 0x02, 0x2b, 0x90, 0x80, 0x71, 0x00, + 0x09, 0x02, 0x3d, 0x61, 0x82, 0xcf, 0x00, 0x09, + 0x03, 0x15, 0x5f, 0x8c, 0x80, 0x30, 0x00, 0x00, + 0x02, 0x28, 0x46, 0x85, 0xb8, 0x00, 0x01, 0x04, + 0x11, 0x33, 0x8b, 0x8a, 0x80, 0x4a, 0x00, 0x01, + 0x02, 0x5c, 0x78, 0x00, 0x00, 0x00, 0x02, 0x5c, + 0x78, 0x84, 0x49, 0x00, 0x00, 0x04, 0x0b, 0x20, + 0x2b, 0x3d, 0x00, 0x01, 0x20, 0x00, 0x04, 0x0b, + 0x20, 0x2b, 0x3d, 0x00, 0x02, 0x20, 0x2b, 0x00, + 0x01, 0x20, 0x01, 0x02, 0x0b, 0x20, 0x00, 0x02, + 0x20, 0x7f, 0x00, 0x02, 0x0b, 0x20, 0x00, 0x02, + 0x20, 0x7f, 0x00, 0x06, 0x20, 0x3d, 0x50, 0x72, + 0x90, 0x92, 0x00, 0x01, 0x20, 0x01, 0x02, 0x20, + 0x7f, 0x01, 0x01, 0x20, 0x00, 0x02, 0x20, 0x7f, + 0x00, 0x02, 0x0b, 0x20, 0x06, 0x01, 0x20, 0x00, + 0x02, 0x20, 0x61, 0x00, 0x02, 0x0b, 0x20, 0x01, + 0x01, 0x20, 0x00, 0x02, 0x0b, 0x20, 0x03, 0x01, + 0x20, 0x00, 0x08, 0x0b, 0x20, 0x2b, 0x3d, 0x61, + 0x72, 0x92, 0x97, 0x00, 0x02, 0x20, 0x2b, 0x00, + 0x03, 0x20, 0x2b, 0x3d, 0x01, 0x02, 0x0b, 0x20, + 0x00, 0x01, 0x0b, 0x01, 0x02, 0x20, 0x2b, 0x00, + 0x01, 0x61, 0x80, 0x44, 0x00, 0x01, 0x01, 0x2c, + 0x35, 0x00, 0x00, 0x02, 0x1d, 0x89, 0x00, 0x00, + 0x00, 0x01, 0x89, 0x81, 0xb3, 0x00, 0x00, 0x02, + 0x46, 0x5c, 0x80, 0x3f, 0x00, 0x00, 0x03, 0x20, + 0x2b, 0x46, 0x8c, 0xd1, 0x00, 0x00, 0x02, 0x1d, + 0x29, 0x81, 0x3c, 0x00, 0x01, 0x06, 0x0d, 0x31, + 0x30, 0x36, 0x3e, 0xa0, 0x00, 0x05, 0x0d, 0x31, + 0x30, 0x36, 0x3e, 0x01, 0x00, 0x00, 0x01, 0x30, + 0x00, 0x00, 0x09, 0x06, 0x0d, 0x31, 0x30, 0x36, + 0x3e, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x0d, 0x31, + 0x30, 0x36, 0x3e, 0x07, 0x06, 0x0d, 0x31, 0x30, + 0x36, 0x3e, 0xa0, 0x03, 0x05, 0x0d, 0x31, 0x30, + 0x36, 0x3e, 0x09, 0x00, 0x03, 0x02, 0x0d, 0x30, + 0x01, 0x00, 0x00, 0x05, 0x0d, 0x31, 0x30, 0x36, + 0x3e, 0x04, 0x02, 0x36, 0x3e, 0x00, 0x00, 0x00, + 0x05, 0x0d, 0x31, 0x30, 0x36, 0x3e, 0x03, 0x00, + 0x01, 0x03, 0x30, 0x36, 0x3e, 0x01, 0x01, 0x30, + 0x58, 0x00, 0x03, 0x02, 0x36, 0x3e, 0x02, 0x00, + 0x00, 0x02, 0x36, 0x3e, 0x59, 0x00, 0x00, 0x06, + 0x0d, 0x31, 0x30, 0x36, 0x3e, 0xa0, 0x00, 0x02, + 0x36, 0x3e, 0x80, 0x12, 0x00, 0x0f, 0x01, 0x30, + 0x1f, 0x00, 0x23, 0x01, 0x30, 0x3b, 0x00, 0x27, + 0x01, 0x30, 0x37, 0x00, 0x30, 0x01, 0x30, 0x0e, + 0x00, 0x0b, 0x01, 0x30, 0x32, 0x00, 0x00, 0x01, + 0x30, 0x57, 0x00, 0x18, 0x01, 0x30, 0x09, 0x00, + 0x04, 0x01, 0x30, 0x5f, 0x00, 0x1e, 0x01, 0x30, + 0xc0, 0x31, 0xef, 0x00, 0x00, 0x02, 0x1d, 0x29, + 0x80, 0x0f, 0x00, 0x07, 0x02, 0x30, 0x46, 0x80, + 0xa7, 0x00, 0x02, 0x0e, 0x20, 0x22, 0x2d, 0x2f, + 0x42, 0x3d, 0x3c, 0x4f, 0x50, 0x5b, 0x61, 0x44, + 0x8f, 0x97, 0x02, 0x0d, 0x20, 0x22, 0x2d, 0x2f, + 0x42, 0x3d, 0x3c, 0x4f, 0x5b, 0x61, 0x44, 0x8f, + 0x97, 0x03, 0x0b, 0x20, 0x22, 0x2d, 0x2f, 0x42, + 0x3c, 0x4f, 0x5b, 0x44, 0x8f, 0x97, 0x80, 0x36, + 0x00, 0x00, 0x02, 0x0b, 0x20, 0x00, 0x00, 0x00, + 0x02, 0x20, 0x90, 0x39, 0x00, 0x00, 0x03, 0x3f, + 0x46, 0x5f, 0x80, 0x1f, 0x00, 0x00, 0x02, 0x10, + 0x3b, 0xc0, 0x12, 0xed, 0x00, 0x01, 0x02, 0x04, + 0x64, 0x80, 0x31, 0x00, 0x00, 0x02, 0x04, 0x93, + 0x09, 0x00, 0x00, 0x02, 0x04, 0x93, 0x46, 0x00, + 0x01, 0x05, 0x0d, 0x31, 0x30, 0x36, 0x3e, 0x80, + 0x99, 0x00, 0x04, 0x06, 0x0d, 0x31, 0x30, 0x36, + 0x3e, 0xa0, 0x09, 0x00, 0x00, 0x02, 0x36, 0x3e, + 0x2c, 0x00, 0x01, 0x02, 0x36, 0x3e, 0x80, 0xdf, + 0x00, 0x01, 0x03, 0x1e, 0x1c, 0x4a, 0x00, 0x02, + 0x1c, 0x4a, 0x03, 0x00, 0x2c, 0x03, 0x1c, 0x49, + 0x4a, 0x02, 0x00, 0x08, 0x02, 0x1c, 0x4a, 0x81, + 0x1f, 0x00, 0x1b, 0x02, 0x04, 0x1a, 0x87, 0x75, + 0x00, 0x00, 0x02, 0x52, 0x71, 0x87, 0x8d, 0x00, + 0x00, 0x02, 0x2b, 0x90, 0x00, 0x00, 0x00, 0x02, + 0x2b, 0x90, 0x36, 0x00, 0x01, 0x02, 0x2b, 0x90, + 0x8c, 0x12, 0x00, 0x01, 0x02, 0x2b, 0x90, 0x00, + 0x00, 0x00, 0x02, 0x2b, 0x90, 0xc0, 0x5c, 0x4b, + 0x00, 0x03, 0x01, 0x23, 0x96, 0x3b, 0x00, 0x11, + 0x01, 0x30, 0x9e, 0x5d, 0x00, 0x01, 0x01, 0x30, + 0xce, 0xcd, 0x2d, 0x00, +}; + +static const uint8_t unicode_prop_Hyphen_table[28] = { + 0xac, 0x80, 0xfe, 0x80, 0x44, 0xdb, 0x80, 0x52, + 0x7a, 0x80, 0x48, 0x08, 0x81, 0x4e, 0x04, 0x80, + 0x42, 0xe2, 0x80, 0x60, 0xcd, 0x66, 0x80, 0x40, + 0xa8, 0x80, 0xd6, 0x80, +}; + +static const uint8_t unicode_prop_Other_Math_table[200] = { + 0xdd, 0x80, 0x43, 0x70, 0x11, 0x80, 0x99, 0x09, + 0x81, 0x5c, 0x1f, 0x80, 0x9a, 0x82, 0x8a, 0x80, + 0x9f, 0x83, 0x97, 0x81, 0x8d, 0x81, 0xc0, 0x8c, + 0x18, 0x11, 0x1c, 0x91, 0x03, 0x01, 0x89, 0x00, + 0x14, 0x28, 0x11, 0x09, 0x02, 0x05, 0x13, 0x24, + 0xca, 0x21, 0x18, 0x08, 0x08, 0x00, 0x21, 0x0b, + 0x0b, 0x91, 0x09, 0x00, 0x06, 0x00, 0x29, 0x41, + 0x21, 0x83, 0x40, 0xa7, 0x08, 0x80, 0x97, 0x80, + 0x90, 0x80, 0x41, 0xbc, 0x81, 0x8b, 0x88, 0x24, + 0x21, 0x09, 0x14, 0x8d, 0x00, 0x01, 0x85, 0x97, + 0x81, 0xb8, 0x00, 0x80, 0x9c, 0x83, 0x88, 0x81, + 0x41, 0x55, 0x81, 0x9e, 0x89, 0x41, 0x92, 0x95, + 0xbe, 0x83, 0x9f, 0x81, 0x60, 0xd4, 0x62, 0x00, + 0x03, 0x80, 0x40, 0xd2, 0x00, 0x80, 0x60, 0xd4, + 0xc0, 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, + 0x80, 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, + 0x06, 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, + 0x41, 0x53, 0x81, 0x98, 0x80, 0x98, 0x80, 0x9e, + 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, + 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x07, 0x81, + 0xb1, 0x55, 0xff, 0x18, 0x9a, 0x01, 0x00, 0x08, + 0x80, 0x89, 0x03, 0x00, 0x00, 0x28, 0x18, 0x00, + 0x00, 0x02, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x0b, 0x06, 0x03, 0x03, 0x00, + 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, 0x80, 0x90, +}; + +static const uint8_t unicode_prop_Other_Alphabetic_table[417] = { + 0x43, 0x44, 0x80, 0x42, 0x69, 0x8d, 0x00, 0x01, + 0x01, 0x00, 0xc7, 0x8a, 0xaf, 0x8c, 0x06, 0x8f, + 0x80, 0xe4, 0x33, 0x19, 0x0b, 0x80, 0xa2, 0x80, + 0x9d, 0x8f, 0xe5, 0x8a, 0xe4, 0x0a, 0x88, 0x02, + 0x03, 0x40, 0xa6, 0x8b, 0x16, 0x85, 0x93, 0xb5, + 0x09, 0x8e, 0x01, 0x22, 0x89, 0x81, 0x9c, 0x82, + 0xb9, 0x31, 0x09, 0x81, 0x89, 0x80, 0x89, 0x81, + 0x9c, 0x82, 0xb9, 0x23, 0x09, 0x0b, 0x80, 0x9d, + 0x0a, 0x80, 0x8a, 0x82, 0xb9, 0x38, 0x10, 0x81, + 0x94, 0x81, 0x95, 0x13, 0x82, 0xb9, 0x31, 0x09, + 0x81, 0x88, 0x81, 0x89, 0x81, 0x9d, 0x80, 0xba, + 0x22, 0x10, 0x82, 0x89, 0x80, 0xa7, 0x83, 0xb9, + 0x30, 0x10, 0x17, 0x81, 0x8a, 0x81, 0x9c, 0x82, + 0xb9, 0x30, 0x10, 0x17, 0x81, 0x8a, 0x81, 0x9b, + 0x83, 0xb9, 0x30, 0x10, 0x82, 0x89, 0x80, 0x89, + 0x81, 0x9c, 0x82, 0xca, 0x28, 0x00, 0x87, 0x91, + 0x81, 0xbc, 0x01, 0x86, 0x91, 0x80, 0xe2, 0x01, + 0x28, 0x81, 0x8f, 0x80, 0x40, 0xa2, 0x90, 0x8a, + 0x8a, 0x80, 0xa3, 0xed, 0x8b, 0x00, 0x0b, 0x96, + 0x1b, 0x10, 0x11, 0x32, 0x83, 0x8c, 0x8b, 0x00, + 0x89, 0x83, 0x46, 0x73, 0x81, 0x9d, 0x81, 0x9d, + 0x81, 0x9d, 0x81, 0xc1, 0x92, 0x40, 0xbb, 0x81, + 0xa1, 0x80, 0xf5, 0x8b, 0x83, 0x88, 0x40, 0xdd, + 0x84, 0xb8, 0x89, 0x81, 0x93, 0xc9, 0x81, 0x8a, + 0x82, 0xb0, 0x84, 0xaf, 0x8e, 0xbb, 0x82, 0x9d, + 0x88, 0x09, 0xb8, 0x8a, 0xb1, 0x92, 0x41, 0xaf, + 0x8d, 0x46, 0xc0, 0xb3, 0x48, 0xf5, 0x9f, 0x60, + 0x78, 0x73, 0x87, 0xa1, 0x81, 0x41, 0x61, 0x07, + 0x80, 0x96, 0x84, 0xd7, 0x81, 0xb1, 0x8f, 0x00, + 0xb8, 0x80, 0xa5, 0x84, 0x9b, 0x8b, 0xac, 0x83, + 0xaf, 0x8b, 0xa4, 0x80, 0xc2, 0x8d, 0x8b, 0x07, + 0x81, 0xac, 0x82, 0xb1, 0x00, 0x11, 0x0c, 0x80, + 0xab, 0x24, 0x80, 0x40, 0xec, 0x87, 0x60, 0x4f, + 0x32, 0x80, 0x48, 0x56, 0x84, 0x46, 0x85, 0x10, + 0x0c, 0x83, 0x43, 0x13, 0x83, 0x41, 0x82, 0x81, + 0x41, 0x52, 0x82, 0xb4, 0x8d, 0xac, 0x81, 0x8c, + 0x80, 0xac, 0x88, 0x88, 0x80, 0xbc, 0x82, 0xa3, + 0x8b, 0x91, 0x81, 0xb8, 0x82, 0xaf, 0x8c, 0x8d, + 0x81, 0xdb, 0x88, 0x08, 0x28, 0x40, 0x9f, 0x89, + 0x96, 0x83, 0xb9, 0x31, 0x09, 0x81, 0x89, 0x80, + 0x89, 0x81, 0x40, 0xd0, 0x8c, 0x02, 0xe9, 0x91, + 0x40, 0xec, 0x31, 0x86, 0x9c, 0x81, 0xd1, 0x8e, + 0x00, 0xe9, 0x8a, 0xe6, 0x8d, 0x41, 0x00, 0x8c, + 0x40, 0xf6, 0x28, 0x09, 0x0a, 0x00, 0x80, 0x40, + 0x8d, 0x31, 0x2b, 0x80, 0x9b, 0x89, 0xa9, 0x20, + 0x83, 0x91, 0x8a, 0xad, 0x8d, 0x41, 0x96, 0x38, + 0x86, 0xd2, 0x95, 0x80, 0x8d, 0xf9, 0x2a, 0x00, + 0x08, 0x10, 0x02, 0x80, 0xc1, 0x20, 0x08, 0x83, + 0x41, 0x5b, 0x83, 0x60, 0x50, 0x57, 0x00, 0xb6, + 0x33, 0xdc, 0x81, 0x60, 0x4c, 0xab, 0x80, 0x60, + 0x23, 0x60, 0x30, 0x90, 0x0e, 0x01, 0x04, 0x49, + 0x1b, 0x80, 0x47, 0xe7, 0x99, 0x85, 0x99, 0x85, + 0x99, +}; + +static const uint8_t unicode_prop_Other_Lowercase_table[59] = { + 0x40, 0xa9, 0x80, 0x8e, 0x80, 0x41, 0xf4, 0x88, + 0x31, 0x9d, 0x84, 0xdf, 0x80, 0xb3, 0x80, 0x59, + 0xb0, 0xbe, 0x8c, 0x80, 0xa1, 0xa4, 0x42, 0xb0, + 0x80, 0x8c, 0x80, 0x8f, 0x8c, 0x40, 0xd2, 0x8f, + 0x43, 0x4f, 0x99, 0x47, 0x91, 0x81, 0x60, 0x7a, + 0x1d, 0x81, 0x40, 0xd1, 0x80, 0x40, 0x86, 0x81, + 0x43, 0x61, 0x83, 0x60, 0x5c, 0x1f, 0x01, 0x10, + 0xa9, 0x80, 0x88, +}; + +static const uint8_t unicode_prop_Other_Uppercase_table[15] = { + 0x60, 0x21, 0x5f, 0x8f, 0x43, 0x45, 0x99, 0x61, + 0xcc, 0x5f, 0x99, 0x85, 0x99, 0x85, 0x99, +}; + +static const uint8_t unicode_prop_Other_Grapheme_Extend_table[65] = { + 0x49, 0xbd, 0x80, 0x97, 0x80, 0x41, 0x65, 0x80, + 0x97, 0x80, 0xe5, 0x80, 0x97, 0x80, 0x40, 0xe9, + 0x80, 0x91, 0x81, 0xe6, 0x80, 0x97, 0x80, 0xf6, + 0x80, 0x8e, 0x80, 0x4d, 0x54, 0x80, 0x44, 0xd5, + 0x80, 0x50, 0x20, 0x81, 0x60, 0xcf, 0x6d, 0x81, + 0x53, 0x9d, 0x80, 0x97, 0x80, 0x41, 0x57, 0x80, + 0x8b, 0x80, 0x40, 0xf0, 0x80, 0x43, 0x7f, 0x80, + 0x60, 0xb8, 0x33, 0x07, 0x84, 0x6c, 0x2e, 0xac, + 0xdf, +}; + +static const uint8_t unicode_prop_Other_Default_Ignorable_Code_Point_table[32] = { + 0x43, 0x4e, 0x80, 0x4e, 0x0e, 0x81, 0x46, 0x52, + 0x81, 0x48, 0xae, 0x80, 0x50, 0xfd, 0x80, 0x60, + 0xce, 0x3a, 0x80, 0xce, 0x88, 0x6d, 0x00, 0x06, + 0x00, 0x9d, 0xdf, 0xff, 0x40, 0xef, 0x4e, 0x0f, +}; + +static const uint8_t unicode_prop_Other_ID_Start_table[11] = { + 0x58, 0x84, 0x81, 0x48, 0x90, 0x80, 0x94, 0x80, + 0x4f, 0x6b, 0x81, +}; + +static const uint8_t unicode_prop_Other_ID_Continue_table[12] = { + 0x40, 0xb6, 0x80, 0x42, 0xce, 0x80, 0x4f, 0xe0, + 0x88, 0x46, 0x67, 0x80, +}; + +static const uint8_t unicode_prop_Prepended_Concatenation_Mark_table[19] = { + 0x45, 0xff, 0x85, 0x40, 0xd6, 0x80, 0xb0, 0x80, + 0x41, 0x7f, 0x81, 0xcf, 0x80, 0x61, 0x07, 0xd9, + 0x80, 0x8e, 0x80, +}; + +static const uint8_t unicode_prop_XID_Start1_table[31] = { + 0x43, 0x79, 0x80, 0x4a, 0xb7, 0x80, 0xfe, 0x80, + 0x60, 0x21, 0xe6, 0x81, 0x60, 0xcb, 0xc0, 0x85, + 0x41, 0x95, 0x81, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x41, 0x1e, 0x81, +}; + +static const uint8_t unicode_prop_XID_Continue1_table[23] = { + 0x43, 0x79, 0x80, 0x60, 0x2d, 0x1f, 0x81, 0x60, + 0xcb, 0xc0, 0x85, 0x41, 0x95, 0x81, 0xf3, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, +}; + +static const uint8_t unicode_prop_Changes_When_Titlecased1_table[22] = { + 0x41, 0xc3, 0x08, 0x08, 0x81, 0xa4, 0x81, 0x4e, + 0xdc, 0xaa, 0x0a, 0x4e, 0x87, 0x3f, 0x3f, 0x87, + 0x8b, 0x80, 0x8e, 0x80, 0xae, 0x80, +}; + +static const uint8_t unicode_prop_Changes_When_Casefolded1_table[33] = { + 0x40, 0xde, 0x80, 0xcf, 0x80, 0x97, 0x80, 0x44, + 0x3c, 0x80, 0x59, 0x11, 0x80, 0x40, 0xe4, 0x3f, + 0x3f, 0x87, 0x89, 0x11, 0x05, 0x02, 0x11, 0x80, + 0xa9, 0x11, 0x80, 0x60, 0xdb, 0x07, 0x86, 0x8b, + 0x84, +}; + +static const uint8_t unicode_prop_Changes_When_NFKC_Casefolded1_table[448] = { + 0x40, 0x9f, 0x06, 0x00, 0x01, 0x00, 0x01, 0x12, + 0x10, 0x82, 0x9f, 0x80, 0xcf, 0x01, 0x80, 0x8b, + 0x07, 0x80, 0xfb, 0x01, 0x01, 0x80, 0xa5, 0x80, + 0x40, 0xbb, 0x88, 0x9e, 0x29, 0x84, 0xda, 0x08, + 0x81, 0x89, 0x80, 0xa3, 0x04, 0x02, 0x04, 0x08, + 0x80, 0xc9, 0x82, 0x9c, 0x80, 0x41, 0x93, 0x80, + 0x40, 0x93, 0x80, 0xd7, 0x83, 0x42, 0xde, 0x87, + 0xfb, 0x08, 0x80, 0xd2, 0x01, 0x80, 0xa1, 0x11, + 0x80, 0x40, 0xfc, 0x81, 0x42, 0xd4, 0x80, 0xfe, + 0x80, 0xa7, 0x81, 0xad, 0x80, 0xb5, 0x80, 0x88, + 0x03, 0x03, 0x03, 0x80, 0x8b, 0x80, 0x88, 0x00, + 0x26, 0x80, 0x90, 0x80, 0x88, 0x03, 0x03, 0x03, + 0x80, 0x8b, 0x80, 0x41, 0x41, 0x80, 0xe1, 0x81, + 0x46, 0x52, 0x81, 0xd4, 0x84, 0x45, 0x1b, 0x10, + 0x8a, 0x80, 0x91, 0x80, 0x9b, 0x8c, 0x80, 0xa1, + 0xa4, 0x40, 0xd9, 0x80, 0x40, 0xd5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x3f, 0x3f, 0x87, + 0x89, 0x11, 0x04, 0x00, 0x29, 0x04, 0x12, 0x80, + 0x88, 0x12, 0x80, 0x88, 0x11, 0x11, 0x04, 0x08, + 0x8f, 0x00, 0x20, 0x8b, 0x12, 0x2a, 0x08, 0x0b, + 0x00, 0x07, 0x82, 0x8c, 0x06, 0x92, 0x81, 0x9a, + 0x80, 0x8c, 0x8a, 0x80, 0xd6, 0x18, 0x10, 0x8a, + 0x01, 0x0c, 0x0a, 0x00, 0x10, 0x11, 0x02, 0x06, + 0x05, 0x1c, 0x85, 0x8f, 0x8f, 0x8f, 0x88, 0x80, + 0x40, 0xa1, 0x08, 0x81, 0x40, 0xf7, 0x81, 0x41, + 0x34, 0xd5, 0x99, 0x9a, 0x45, 0x20, 0x80, 0xe6, + 0x82, 0xe4, 0x80, 0x41, 0x9e, 0x81, 0x40, 0xf0, + 0x80, 0x41, 0x2e, 0x80, 0xd2, 0x80, 0x8b, 0x40, + 0xd5, 0xa9, 0x80, 0xb4, 0x00, 0x82, 0xdf, 0x09, + 0x80, 0xde, 0x80, 0xb0, 0xdd, 0x82, 0x8d, 0xdf, + 0x9e, 0x80, 0xa7, 0x87, 0xae, 0x80, 0x41, 0x7f, + 0x60, 0x72, 0x9b, 0x81, 0x40, 0xd1, 0x80, 0x40, + 0x80, 0x12, 0x81, 0x43, 0x61, 0x83, 0x88, 0x80, + 0x60, 0x4d, 0x95, 0x41, 0x0d, 0x08, 0x00, 0x81, + 0x89, 0x00, 0x00, 0x09, 0x82, 0xc3, 0x81, 0xe9, + 0xa5, 0x86, 0x8b, 0x24, 0x00, 0x97, 0x04, 0x00, + 0x01, 0x01, 0x80, 0xeb, 0xa0, 0x41, 0x6a, 0x91, + 0xbf, 0x81, 0xb5, 0xa7, 0x8c, 0x82, 0x99, 0x95, + 0x94, 0x81, 0x8b, 0x80, 0x92, 0x03, 0x1a, 0x00, + 0x80, 0x40, 0x86, 0x08, 0x80, 0x9f, 0x99, 0x40, + 0x83, 0x15, 0x0d, 0x0d, 0x0a, 0x16, 0x06, 0x80, + 0x88, 0x47, 0x87, 0x20, 0xa9, 0x80, 0x88, 0x60, + 0xb4, 0xe4, 0x83, 0x54, 0xb9, 0x86, 0x8d, 0x87, + 0xbf, 0x85, 0x42, 0x3e, 0xd4, 0x80, 0xc6, 0x01, + 0x08, 0x09, 0x0b, 0x80, 0x8b, 0x00, 0x06, 0x80, + 0xc0, 0x03, 0x0f, 0x06, 0x80, 0x9b, 0x03, 0x04, + 0x00, 0x16, 0x80, 0x41, 0x53, 0x81, 0x41, 0x23, + 0x81, 0xb1, 0x55, 0xff, 0x18, 0x9a, 0x01, 0x00, + 0x08, 0x80, 0x89, 0x03, 0x00, 0x00, 0x28, 0x18, + 0x00, 0x00, 0x02, 0x01, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x0b, 0x06, 0x03, 0x03, + 0x00, 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, 0x80, + 0x90, 0x42, 0x43, 0x8a, 0x84, 0x9e, 0x80, 0x9f, + 0x99, 0x82, 0xa2, 0x80, 0xee, 0x82, 0x8c, 0xab, + 0x83, 0x88, 0x31, 0x49, 0x9d, 0x89, 0x60, 0xfc, + 0x05, 0x42, 0x1d, 0x6b, 0x05, 0xe1, 0x4f, 0xff, +}; + +static const uint8_t unicode_prop_ASCII_Hex_Digit_table[5] = { + 0xaf, 0x89, 0x35, 0x99, 0x85, +}; + +static const uint8_t unicode_prop_Bidi_Control_table[10] = { + 0x46, 0x1b, 0x80, 0x59, 0xf0, 0x81, 0x99, 0x84, + 0xb6, 0x83, +}; + +static const uint8_t unicode_prop_Dash_table[55] = { + 0xac, 0x80, 0x45, 0x5b, 0x80, 0xb2, 0x80, 0x4e, + 0x40, 0x80, 0x44, 0x04, 0x80, 0x48, 0x08, 0x85, + 0xbc, 0x80, 0xa6, 0x80, 0x8e, 0x80, 0x41, 0x85, + 0x80, 0x4c, 0x03, 0x01, 0x80, 0x9e, 0x0b, 0x80, + 0x9b, 0x80, 0x41, 0xbd, 0x80, 0x92, 0x80, 0xee, + 0x80, 0x60, 0xcd, 0x8f, 0x81, 0xa4, 0x80, 0x89, + 0x80, 0x40, 0xa8, 0x80, 0x4f, 0x9e, 0x80, +}; + +static const uint8_t unicode_prop_Deprecated_table[23] = { + 0x41, 0x48, 0x80, 0x45, 0x28, 0x80, 0x49, 0x02, + 0x00, 0x80, 0x48, 0x28, 0x81, 0x48, 0xc4, 0x85, + 0x42, 0xb8, 0x81, 0x6d, 0xdc, 0xd5, 0x80, +}; + +static const uint8_t unicode_prop_Diacritic_table[391] = { + 0xdd, 0x00, 0x80, 0xc6, 0x05, 0x03, 0x01, 0x81, + 0x41, 0xf6, 0x40, 0x9e, 0x07, 0x25, 0x90, 0x0b, + 0x80, 0x88, 0x81, 0x40, 0xfc, 0x84, 0x40, 0xd0, + 0x80, 0xb6, 0x90, 0x80, 0x9a, 0x00, 0x01, 0x00, + 0x40, 0x85, 0x3b, 0x81, 0x40, 0x85, 0x0b, 0x0a, + 0x82, 0xc2, 0x9a, 0xda, 0x8a, 0xb9, 0x8a, 0xa1, + 0x81, 0xfd, 0x87, 0xa8, 0x89, 0x8f, 0x9b, 0xbc, + 0x80, 0x8f, 0x02, 0x83, 0x9b, 0x80, 0xc9, 0x80, + 0x8f, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xed, 0x80, + 0x8f, 0x80, 0xae, 0x82, 0xbb, 0x80, 0x8f, 0x06, + 0x80, 0xf6, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xed, + 0x80, 0x8f, 0x80, 0xec, 0x81, 0x8f, 0x80, 0xfb, + 0x80, 0xfb, 0x28, 0x80, 0xea, 0x80, 0x8c, 0x84, + 0xca, 0x81, 0x9a, 0x00, 0x00, 0x03, 0x81, 0xc1, + 0x10, 0x81, 0xbd, 0x80, 0xef, 0x00, 0x81, 0xa7, + 0x0b, 0x84, 0x98, 0x30, 0x80, 0x89, 0x81, 0x42, + 0xc0, 0x82, 0x43, 0xb3, 0x81, 0x40, 0xb2, 0x8a, + 0x88, 0x80, 0x41, 0x5a, 0x82, 0x41, 0x38, 0x39, + 0x80, 0xaf, 0x8e, 0x81, 0x8a, 0xe7, 0x80, 0x8e, + 0x80, 0xa5, 0x88, 0xb5, 0x81, 0x40, 0x89, 0x81, + 0xbf, 0x85, 0xd1, 0x98, 0x18, 0x28, 0x0a, 0xb1, + 0xbe, 0xd8, 0x8b, 0xa4, 0x8a, 0x41, 0xbc, 0x00, + 0x82, 0x8a, 0x82, 0x8c, 0x82, 0x8c, 0x82, 0x8c, + 0x81, 0x4c, 0xef, 0x82, 0x41, 0x3c, 0x80, 0x41, + 0xf9, 0x85, 0xe8, 0x83, 0xde, 0x80, 0x60, 0x75, + 0x71, 0x80, 0x8b, 0x08, 0x80, 0x9b, 0x81, 0xd1, + 0x81, 0x8d, 0xa1, 0xe5, 0x82, 0xec, 0x81, 0x40, + 0xc9, 0x80, 0x9a, 0x91, 0xb8, 0x83, 0xa3, 0x80, + 0xde, 0x80, 0x8b, 0x80, 0xa3, 0x80, 0x40, 0x94, + 0x82, 0xc0, 0x83, 0xb2, 0x80, 0xe3, 0x84, 0x88, + 0x82, 0xff, 0x81, 0x60, 0x4f, 0x2f, 0x80, 0x43, + 0x00, 0x8f, 0x41, 0x0d, 0x00, 0x80, 0xae, 0x80, + 0xac, 0x81, 0xc2, 0x80, 0x42, 0xfb, 0x80, 0x44, + 0x9e, 0x28, 0xa9, 0x80, 0x88, 0x43, 0x29, 0x81, + 0x42, 0x3a, 0x85, 0x42, 0x1d, 0x8a, 0xb0, 0x83, + 0x40, 0xbf, 0x80, 0xa8, 0x80, 0xc7, 0x81, 0xf7, + 0x81, 0xbd, 0x80, 0xcb, 0x80, 0x88, 0x82, 0xe7, + 0x81, 0x40, 0xb1, 0x81, 0xd0, 0x80, 0x8f, 0x80, + 0x97, 0x32, 0x84, 0x40, 0xcc, 0x02, 0x80, 0xfa, + 0x81, 0x40, 0xfa, 0x81, 0xfd, 0x80, 0xf5, 0x81, + 0xf2, 0x80, 0x41, 0x0c, 0x81, 0x41, 0x01, 0x0b, + 0x80, 0x40, 0x9b, 0x80, 0xd2, 0x80, 0x91, 0x80, + 0xd0, 0x80, 0x41, 0xa4, 0x80, 0x41, 0x01, 0x00, + 0x81, 0xd0, 0x80, 0x60, 0x4d, 0x57, 0x84, 0xba, + 0x86, 0x44, 0x57, 0x90, 0xcf, 0x81, 0x60, 0x3f, + 0xfd, 0x18, 0x30, 0x81, 0x5f, 0x00, 0xad, 0x81, + 0x96, 0x42, 0x1f, 0x12, 0x2f, 0x39, 0x86, 0x9d, + 0x83, 0x4f, 0x81, 0x86, 0x41, 0x76, 0x80, 0xbc, + 0x83, 0x45, 0xdf, 0x86, 0xec, 0x10, 0x82, +}; + +static const uint8_t unicode_prop_Extender_table[92] = { + 0x40, 0xb6, 0x80, 0x42, 0x17, 0x81, 0x43, 0x6d, + 0x80, 0x41, 0xb8, 0x80, 0x43, 0x59, 0x80, 0x42, + 0xef, 0x80, 0xfe, 0x80, 0x49, 0x42, 0x80, 0xb7, + 0x80, 0x42, 0x62, 0x80, 0x41, 0x8d, 0x80, 0xc3, + 0x80, 0x53, 0x88, 0x80, 0xaa, 0x84, 0xe6, 0x81, + 0xdc, 0x82, 0x60, 0x6f, 0x15, 0x80, 0x45, 0xf5, + 0x80, 0x43, 0xc1, 0x80, 0x95, 0x80, 0x40, 0x88, + 0x80, 0xeb, 0x80, 0x94, 0x81, 0x60, 0x54, 0x7a, + 0x80, 0x48, 0x0f, 0x81, 0x4b, 0xd9, 0x80, 0x42, + 0x67, 0x82, 0x44, 0xce, 0x80, 0x60, 0x50, 0xa8, + 0x81, 0x44, 0x9b, 0x08, 0x80, 0x60, 0x71, 0x57, + 0x81, 0x48, 0x05, 0x82, +}; + +static const uint8_t unicode_prop_Hex_Digit_table[12] = { + 0xaf, 0x89, 0x35, 0x99, 0x85, 0x60, 0xfe, 0xa8, + 0x89, 0x35, 0x99, 0x85, +}; + +static const uint8_t unicode_prop_IDS_Binary_Operator_table[5] = { + 0x60, 0x2f, 0xef, 0x09, 0x87, +}; + +static const uint8_t unicode_prop_IDS_Trinary_Operator_table[4] = { + 0x60, 0x2f, 0xf1, 0x81, +}; + +static const uint8_t unicode_prop_Ideographic_table[66] = { + 0x60, 0x30, 0x05, 0x81, 0x98, 0x88, 0x8d, 0x82, + 0x43, 0xc4, 0x59, 0xbf, 0xbf, 0x60, 0x51, 0xff, + 0x60, 0x58, 0xff, 0x41, 0x6d, 0x81, 0xe9, 0x60, + 0x75, 0x09, 0x80, 0x9a, 0x57, 0xf7, 0x87, 0x44, + 0xd5, 0xa9, 0x88, 0x60, 0x24, 0x66, 0x41, 0x8b, + 0x60, 0x4d, 0x03, 0x60, 0xa6, 0xdf, 0x9f, 0x50, + 0x38, 0x86, 0x40, 0xdd, 0x81, 0x56, 0x81, 0x8d, + 0x5d, 0x30, 0x4c, 0x1e, 0x42, 0x1d, 0x45, 0xe1, + 0x53, 0x4a, +}; + +static const uint8_t unicode_prop_Join_Control_table[4] = { + 0x60, 0x20, 0x0b, 0x81, +}; + +static const uint8_t unicode_prop_Logical_Order_Exception_table[15] = { + 0x4e, 0x3f, 0x84, 0xfa, 0x84, 0x4a, 0xef, 0x11, + 0x80, 0x60, 0x90, 0xf9, 0x09, 0x00, 0x81, +}; + +static const uint8_t unicode_prop_Noncharacter_Code_Point_table[71] = { + 0x60, 0xfd, 0xcf, 0x9f, 0x42, 0x0d, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, +}; + +static const uint8_t unicode_prop_Pattern_Syntax_table[58] = { + 0xa0, 0x8e, 0x89, 0x86, 0x99, 0x18, 0x80, 0x99, + 0x83, 0xa1, 0x30, 0x00, 0x08, 0x00, 0x0b, 0x03, + 0x02, 0x80, 0x96, 0x80, 0x9e, 0x80, 0x5f, 0x17, + 0x97, 0x87, 0x8e, 0x81, 0x92, 0x80, 0x89, 0x41, + 0x30, 0x42, 0xcf, 0x40, 0x9f, 0x42, 0x75, 0x9d, + 0x44, 0x6b, 0x41, 0xff, 0xff, 0x41, 0x80, 0x13, + 0x98, 0x8e, 0x80, 0x60, 0xcd, 0x0c, 0x81, 0x41, + 0x04, 0x81, +}; + +static const uint8_t unicode_prop_Pattern_White_Space_table[11] = { + 0x88, 0x84, 0x91, 0x80, 0xe3, 0x80, 0x5f, 0x87, + 0x81, 0x97, 0x81, +}; + +static const uint8_t unicode_prop_Quotation_Mark_table[31] = { + 0xa1, 0x03, 0x80, 0x40, 0x82, 0x80, 0x8e, 0x80, + 0x5f, 0x5b, 0x87, 0x98, 0x81, 0x4e, 0x06, 0x80, + 0x41, 0xc8, 0x83, 0x8c, 0x82, 0x60, 0xce, 0x20, + 0x83, 0x40, 0xbc, 0x03, 0x80, 0xd9, 0x81, +}; + +static const uint8_t unicode_prop_Radical_table[9] = { + 0x60, 0x2e, 0x7f, 0x99, 0x80, 0xd8, 0x8b, 0x40, + 0xd5, +}; + +static const uint8_t unicode_prop_Regional_Indicator_table[4] = { + 0x61, 0xf1, 0xe5, 0x99, +}; + +static const uint8_t unicode_prop_Sentence_Terminal_table[194] = { + 0xa0, 0x80, 0x8b, 0x80, 0x8f, 0x80, 0x45, 0x48, + 0x80, 0x40, 0x92, 0x82, 0x40, 0xb3, 0x80, 0xaa, + 0x82, 0x40, 0xf5, 0x80, 0xbc, 0x00, 0x02, 0x81, + 0x41, 0x24, 0x81, 0x46, 0xe3, 0x81, 0x43, 0x15, + 0x03, 0x81, 0x43, 0x04, 0x80, 0x40, 0xc5, 0x81, + 0x40, 0xcb, 0x04, 0x80, 0x41, 0x39, 0x81, 0x41, + 0x61, 0x83, 0x40, 0xad, 0x09, 0x81, 0x9c, 0x81, + 0x40, 0xbb, 0x81, 0xc0, 0x81, 0x43, 0xbb, 0x81, + 0x88, 0x82, 0x4d, 0xe3, 0x80, 0x8c, 0x80, 0x95, + 0x81, 0x41, 0xac, 0x80, 0x60, 0x74, 0xfb, 0x80, + 0x41, 0x0d, 0x81, 0x40, 0xe2, 0x02, 0x80, 0x41, + 0x7d, 0x81, 0xd5, 0x81, 0xde, 0x80, 0x40, 0x97, + 0x81, 0x40, 0x92, 0x82, 0x40, 0x8f, 0x81, 0x40, + 0xf8, 0x80, 0x60, 0x52, 0x65, 0x02, 0x81, 0x40, + 0xa8, 0x80, 0x8b, 0x80, 0x8f, 0x80, 0xc0, 0x80, + 0x4a, 0xf3, 0x81, 0x44, 0xfc, 0x84, 0xab, 0x83, + 0x40, 0xbc, 0x81, 0xf4, 0x83, 0xfe, 0x82, 0x40, + 0x80, 0x0d, 0x80, 0x8f, 0x81, 0xd7, 0x08, 0x81, + 0xeb, 0x80, 0x41, 0xa0, 0x81, 0x41, 0x74, 0x0c, + 0x8e, 0xe8, 0x81, 0x40, 0xf8, 0x82, 0x42, 0x04, + 0x00, 0x80, 0x40, 0xfa, 0x81, 0xd6, 0x81, 0x41, + 0xa3, 0x81, 0x42, 0xb3, 0x81, 0x60, 0x4b, 0x74, + 0x81, 0x40, 0x84, 0x80, 0xc0, 0x81, 0x8a, 0x80, + 0x43, 0x52, 0x80, 0x60, 0x4e, 0x05, 0x80, 0x5d, + 0xe7, 0x80, +}; + +static const uint8_t unicode_prop_Soft_Dotted_table[74] = { + 0xe8, 0x81, 0x40, 0xc3, 0x80, 0x41, 0x18, 0x80, + 0x9d, 0x80, 0xb3, 0x80, 0x93, 0x80, 0x41, 0x3f, + 0x80, 0xe1, 0x00, 0x80, 0x59, 0x08, 0x80, 0xb2, + 0x80, 0x8c, 0x02, 0x80, 0x40, 0x83, 0x80, 0x40, + 0x9c, 0x80, 0x41, 0xa4, 0x80, 0x40, 0xd5, 0x81, + 0x4b, 0x31, 0x80, 0x61, 0xa7, 0xa4, 0x81, 0xb1, + 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, + 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, + 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0x48, + 0x85, 0x80, +}; + +static const uint8_t unicode_prop_Terminal_Punctuation_table[246] = { + 0xa0, 0x80, 0x89, 0x00, 0x80, 0x8a, 0x0a, 0x80, + 0x43, 0x3d, 0x07, 0x80, 0x42, 0x00, 0x80, 0xb8, + 0x80, 0xc7, 0x80, 0x8d, 0x00, 0x82, 0x40, 0xb3, + 0x80, 0xaa, 0x8a, 0x00, 0x40, 0xea, 0x81, 0xb5, + 0x8e, 0x9e, 0x80, 0x41, 0x04, 0x81, 0x44, 0xf3, + 0x81, 0x40, 0xab, 0x03, 0x85, 0x41, 0x36, 0x81, + 0x43, 0x14, 0x87, 0x43, 0x04, 0x80, 0xfb, 0x82, + 0xc6, 0x81, 0x40, 0x9c, 0x12, 0x80, 0xa6, 0x19, + 0x81, 0x41, 0x39, 0x81, 0x41, 0x61, 0x83, 0x40, + 0xad, 0x08, 0x82, 0x9c, 0x81, 0x40, 0xbb, 0x84, + 0xbd, 0x81, 0x43, 0xbb, 0x81, 0x88, 0x82, 0x4d, + 0xe3, 0x80, 0x8c, 0x03, 0x80, 0x89, 0x00, 0x0a, + 0x81, 0x41, 0xab, 0x81, 0x60, 0x74, 0xfa, 0x81, + 0x41, 0x0c, 0x82, 0x40, 0xe2, 0x84, 0x41, 0x7d, + 0x81, 0xd5, 0x81, 0xde, 0x80, 0x40, 0x96, 0x82, + 0x40, 0x92, 0x82, 0xfe, 0x80, 0x8f, 0x81, 0x40, + 0xf8, 0x80, 0x60, 0x52, 0x63, 0x10, 0x83, 0x40, + 0xa8, 0x80, 0x89, 0x00, 0x80, 0x8a, 0x0a, 0x80, + 0xc0, 0x01, 0x80, 0x44, 0x39, 0x80, 0xaf, 0x80, + 0x44, 0x85, 0x80, 0x40, 0xc6, 0x80, 0x41, 0x35, + 0x81, 0x40, 0x97, 0x85, 0xc3, 0x85, 0xd8, 0x83, + 0x43, 0xb7, 0x84, 0xab, 0x83, 0x40, 0xbc, 0x86, + 0xef, 0x83, 0xfe, 0x82, 0x40, 0x80, 0x0d, 0x80, + 0x8f, 0x81, 0xd7, 0x84, 0xeb, 0x80, 0x41, 0xa0, + 0x82, 0x8b, 0x81, 0x41, 0x65, 0x1a, 0x8e, 0xe8, + 0x81, 0x40, 0xf8, 0x82, 0x42, 0x04, 0x00, 0x80, + 0x40, 0xfa, 0x81, 0xd6, 0x0b, 0x81, 0x41, 0x9d, + 0x82, 0xac, 0x80, 0x42, 0x84, 0x81, 0x45, 0x76, + 0x84, 0x60, 0x45, 0xf8, 0x81, 0x40, 0x84, 0x80, + 0xc0, 0x82, 0x89, 0x80, 0x43, 0x51, 0x81, 0x60, + 0x4e, 0x05, 0x80, 0x5d, 0xe6, 0x83, +}; + +static const uint8_t unicode_prop_Unified_Ideograph_table[42] = { + 0x60, 0x33, 0xff, 0x59, 0xbf, 0xbf, 0x60, 0x51, + 0xff, 0x60, 0x5a, 0x0d, 0x08, 0x00, 0x81, 0x89, + 0x00, 0x00, 0x09, 0x82, 0x61, 0x05, 0xd5, 0x60, + 0xa6, 0xdf, 0x9f, 0x50, 0x38, 0x86, 0x40, 0xdd, + 0x81, 0x56, 0x81, 0x8d, 0x5d, 0x30, 0x54, 0x1e, + 0x53, 0x4a, +}; + +static const uint8_t unicode_prop_Variation_Selector_table[13] = { + 0x58, 0x0a, 0x10, 0x80, 0x60, 0xe5, 0xef, 0x8f, + 0x6d, 0x02, 0xef, 0x40, 0xef, +}; + +static const uint8_t unicode_prop_White_Space_table[22] = { + 0x88, 0x84, 0x91, 0x80, 0xe3, 0x80, 0x99, 0x80, + 0x55, 0xde, 0x80, 0x49, 0x7e, 0x8a, 0x9c, 0x0c, + 0x80, 0xae, 0x80, 0x4f, 0x9f, 0x80, +}; + +static const uint8_t unicode_prop_Bidi_Mirrored_table[173] = { + 0xa7, 0x81, 0x91, 0x00, 0x80, 0x9b, 0x00, 0x80, + 0x9c, 0x00, 0x80, 0xac, 0x80, 0x8e, 0x80, 0x4e, + 0x7d, 0x83, 0x47, 0x5c, 0x81, 0x49, 0x9b, 0x81, + 0x89, 0x81, 0xb5, 0x81, 0x8d, 0x81, 0x40, 0xb0, + 0x80, 0x40, 0xbf, 0x1a, 0x2a, 0x02, 0x0a, 0x18, + 0x18, 0x00, 0x03, 0x88, 0x20, 0x80, 0x91, 0x23, + 0x88, 0x08, 0x00, 0x39, 0x9e, 0x0b, 0x20, 0x88, + 0x09, 0x92, 0x21, 0x88, 0x21, 0x0b, 0x97, 0x81, + 0x8f, 0x3b, 0x93, 0x0e, 0x81, 0x44, 0x3c, 0x8d, + 0xc9, 0x01, 0x18, 0x08, 0x14, 0x1c, 0x12, 0x8d, + 0x41, 0x92, 0x95, 0x0d, 0x80, 0x8d, 0x38, 0x35, + 0x10, 0x1c, 0x01, 0x0c, 0x18, 0x02, 0x09, 0x89, + 0x29, 0x81, 0x8b, 0x92, 0x03, 0x08, 0x00, 0x08, + 0x03, 0x21, 0x2a, 0x97, 0x81, 0x8a, 0x0b, 0x18, + 0x09, 0x0b, 0xaa, 0x0f, 0x80, 0xa7, 0x20, 0x00, + 0x14, 0x22, 0x18, 0x14, 0x00, 0x40, 0xff, 0x80, + 0x42, 0x02, 0x1a, 0x08, 0x81, 0x8d, 0x09, 0x89, + 0xaa, 0x87, 0x41, 0xaa, 0x89, 0x0f, 0x60, 0xce, + 0x3c, 0x2c, 0x81, 0x40, 0xa1, 0x81, 0x91, 0x00, + 0x80, 0x9b, 0x00, 0x80, 0x9c, 0x00, 0x00, 0x08, + 0x81, 0x60, 0xd7, 0x76, 0x80, 0xb8, 0x80, 0xb8, + 0x80, 0xb8, 0x80, 0xb8, 0x80, +}; + +static const uint8_t unicode_prop_Emoji_table[239] = { + 0xa2, 0x05, 0x04, 0x89, 0xee, 0x03, 0x80, 0x5f, + 0x8c, 0x80, 0x8b, 0x80, 0x40, 0xd7, 0x80, 0x95, + 0x80, 0xd9, 0x85, 0x8e, 0x81, 0x41, 0x6e, 0x81, + 0x8b, 0x80, 0x40, 0xa5, 0x80, 0x98, 0x8a, 0x1a, + 0x40, 0xc6, 0x80, 0x40, 0xe6, 0x81, 0x89, 0x80, + 0x88, 0x80, 0xb9, 0x18, 0x84, 0x88, 0x01, 0x01, + 0x09, 0x03, 0x01, 0x00, 0x09, 0x02, 0x02, 0x0f, + 0x14, 0x00, 0x04, 0x8b, 0x8a, 0x09, 0x00, 0x08, + 0x80, 0x91, 0x01, 0x81, 0x91, 0x28, 0x00, 0x0a, + 0x0c, 0x01, 0x0b, 0x81, 0x8a, 0x0c, 0x09, 0x04, + 0x08, 0x00, 0x81, 0x93, 0x0c, 0x28, 0x19, 0x03, + 0x01, 0x01, 0x28, 0x01, 0x00, 0x00, 0x05, 0x02, + 0x05, 0x80, 0x89, 0x81, 0x8e, 0x01, 0x03, 0x00, + 0x03, 0x10, 0x80, 0x8a, 0x81, 0xaf, 0x82, 0x88, + 0x80, 0x8d, 0x80, 0x8d, 0x80, 0x41, 0x73, 0x81, + 0x41, 0xce, 0x82, 0x92, 0x81, 0xb2, 0x03, 0x80, + 0x44, 0xd9, 0x80, 0x8b, 0x80, 0x42, 0x58, 0x00, + 0x80, 0x61, 0xbd, 0x69, 0x80, 0x40, 0xc9, 0x80, + 0x40, 0x9f, 0x81, 0x8b, 0x81, 0x8d, 0x01, 0x89, + 0xca, 0x99, 0x01, 0x96, 0x80, 0x93, 0x01, 0x88, + 0x94, 0x81, 0x40, 0xad, 0xa1, 0x81, 0xef, 0x09, + 0x02, 0x81, 0xd2, 0x0a, 0x80, 0x41, 0x06, 0x80, + 0xbe, 0x8a, 0x28, 0x97, 0x31, 0x0f, 0x8b, 0x01, + 0x19, 0x03, 0x81, 0x8c, 0x09, 0x07, 0x81, 0x88, + 0x04, 0x82, 0x8b, 0x17, 0x11, 0x00, 0x03, 0x05, + 0x02, 0x05, 0xd5, 0xaf, 0xc5, 0x27, 0x0a, 0x84, + 0x88, 0x10, 0x01, 0x10, 0x81, 0x89, 0x40, 0xe2, + 0x8b, 0x18, 0x41, 0x1a, 0xae, 0x80, 0x89, 0x80, + 0x40, 0xb8, 0xef, 0x22, 0x22, 0x86, 0x88, 0x9c, + 0x82, 0x8a, 0x25, 0x89, 0x89, 0x2f, 0x3e, +}; + +static const uint8_t unicode_prop_Emoji_Component_table[28] = { + 0xa2, 0x05, 0x04, 0x89, 0x5f, 0xd2, 0x80, 0x40, + 0xd4, 0x80, 0x60, 0xdd, 0x2a, 0x80, 0x60, 0xf3, + 0xd5, 0x99, 0x41, 0xfa, 0x84, 0x45, 0xaf, 0x83, + 0x6c, 0x06, 0x6b, 0xdf, +}; + +static const uint8_t unicode_prop_Emoji_Modifier_table[4] = { + 0x61, 0xf3, 0xfa, 0x84, +}; + +static const uint8_t unicode_prop_Emoji_Modifier_Base_table[71] = { + 0x60, 0x26, 0x1c, 0x80, 0x40, 0xda, 0x80, 0x8f, + 0x83, 0x61, 0xcc, 0x76, 0x80, 0xbb, 0x11, 0x01, + 0x82, 0xf4, 0x09, 0x8a, 0x94, 0x92, 0x10, 0x1a, + 0x02, 0x30, 0x00, 0x97, 0x80, 0x40, 0xc8, 0x0b, + 0x80, 0x94, 0x03, 0x81, 0x40, 0xad, 0x12, 0x84, + 0xd2, 0x80, 0x8f, 0x82, 0x88, 0x80, 0x8a, 0x80, + 0x42, 0x3e, 0x01, 0x07, 0x3d, 0x80, 0x88, 0x89, + 0x0a, 0xb7, 0x80, 0xbc, 0x08, 0x08, 0x80, 0x90, + 0x10, 0x8c, 0x40, 0xe4, 0x82, 0xa9, 0x86, +}; + +static const uint8_t unicode_prop_Emoji_Presentation_table[145] = { + 0x60, 0x23, 0x19, 0x81, 0x40, 0xcc, 0x1a, 0x01, + 0x80, 0x42, 0x08, 0x81, 0x94, 0x81, 0xb1, 0x8b, + 0xaa, 0x80, 0x92, 0x80, 0x8c, 0x07, 0x81, 0x90, + 0x0c, 0x0f, 0x04, 0x80, 0x94, 0x06, 0x08, 0x03, + 0x01, 0x06, 0x03, 0x81, 0x9b, 0x80, 0xa2, 0x00, + 0x03, 0x10, 0x80, 0xbc, 0x82, 0x97, 0x80, 0x8d, + 0x80, 0x43, 0x5a, 0x81, 0xb2, 0x03, 0x80, 0x61, + 0xc4, 0xad, 0x80, 0x40, 0xc9, 0x80, 0x40, 0xbd, + 0x01, 0x89, 0xca, 0x99, 0x00, 0x97, 0x80, 0x93, + 0x01, 0x20, 0x82, 0x94, 0x81, 0x40, 0xad, 0xa0, + 0x8b, 0x88, 0x80, 0xc5, 0x80, 0x95, 0x8b, 0xaa, + 0x1c, 0x8b, 0x90, 0x10, 0x82, 0xc6, 0x00, 0x80, + 0x40, 0xba, 0x81, 0xbe, 0x8c, 0x18, 0x97, 0x91, + 0x80, 0x99, 0x81, 0x8c, 0x80, 0xd5, 0xd4, 0xaf, + 0xc5, 0x28, 0x12, 0x0a, 0x22, 0x8a, 0x0e, 0x88, + 0x40, 0xe2, 0x8b, 0x18, 0x41, 0x1a, 0xae, 0x80, + 0x89, 0x80, 0x40, 0xb8, 0xef, 0x22, 0x22, 0x86, + 0x88, 0x9c, 0x82, 0x8a, 0x25, 0x89, 0x89, 0x2f, + 0x3e, +}; + +static const uint8_t unicode_prop_Extended_Pictographic_table[156] = { + 0x40, 0xa8, 0x03, 0x80, 0x5f, 0x8c, 0x80, 0x8b, + 0x80, 0x40, 0xd7, 0x80, 0x95, 0x80, 0xd9, 0x85, + 0x8e, 0x81, 0x41, 0x6e, 0x81, 0x8b, 0x80, 0xde, + 0x80, 0xc5, 0x80, 0x98, 0x8a, 0x1a, 0x40, 0xc6, + 0x80, 0x40, 0xe6, 0x81, 0x89, 0x80, 0x88, 0x80, + 0xb9, 0x18, 0x28, 0x8b, 0x80, 0xf1, 0x89, 0xf5, + 0x81, 0x8a, 0x00, 0x00, 0x28, 0x10, 0x28, 0x89, + 0x81, 0x8e, 0x01, 0x03, 0x00, 0x03, 0x10, 0x80, + 0x8a, 0x84, 0xac, 0x82, 0x88, 0x80, 0x8d, 0x80, + 0x8d, 0x80, 0x41, 0x73, 0x81, 0x41, 0xce, 0x82, + 0x92, 0x81, 0xb2, 0x03, 0x80, 0x44, 0xd9, 0x80, + 0x8b, 0x80, 0x42, 0x58, 0x00, 0x80, 0x61, 0xbd, + 0x65, 0x40, 0xff, 0x8c, 0x82, 0x9e, 0x80, 0xbb, + 0x85, 0x8b, 0x81, 0x8d, 0x01, 0x89, 0x91, 0xb8, + 0x9a, 0x8e, 0x89, 0x80, 0x93, 0x01, 0x88, 0x03, + 0x88, 0x41, 0xb1, 0x84, 0x41, 0x3d, 0x87, 0x41, + 0x09, 0xaf, 0xff, 0xf3, 0x8b, 0xd4, 0xaa, 0x8b, + 0x83, 0xb7, 0x87, 0x89, 0x85, 0xa7, 0x87, 0x9d, + 0xd1, 0x8b, 0xae, 0x80, 0x89, 0x80, 0x41, 0xb8, + 0x40, 0xff, 0x43, 0xfd, +}; + +static const uint8_t unicode_prop_Default_Ignorable_Code_Point_table[51] = { + 0x40, 0xac, 0x80, 0x42, 0xa0, 0x80, 0x42, 0xcb, + 0x80, 0x4b, 0x41, 0x81, 0x46, 0x52, 0x81, 0xd4, + 0x84, 0x47, 0xfa, 0x84, 0x99, 0x84, 0xb0, 0x8f, + 0x50, 0xf3, 0x80, 0x60, 0xcc, 0x9a, 0x8f, 0x40, + 0xee, 0x80, 0x40, 0x9f, 0x80, 0xce, 0x88, 0x60, + 0xbc, 0xa6, 0x83, 0x54, 0xce, 0x87, 0x6c, 0x2e, + 0x84, 0x4f, 0xff, +}; + +typedef enum { + UNICODE_PROP_Hyphen, + UNICODE_PROP_Other_Math, + UNICODE_PROP_Other_Alphabetic, + UNICODE_PROP_Other_Lowercase, + UNICODE_PROP_Other_Uppercase, + UNICODE_PROP_Other_Grapheme_Extend, + UNICODE_PROP_Other_Default_Ignorable_Code_Point, + UNICODE_PROP_Other_ID_Start, + UNICODE_PROP_Other_ID_Continue, + UNICODE_PROP_Prepended_Concatenation_Mark, + UNICODE_PROP_ID_Continue1, + UNICODE_PROP_XID_Start1, + UNICODE_PROP_XID_Continue1, + UNICODE_PROP_Changes_When_Titlecased1, + UNICODE_PROP_Changes_When_Casefolded1, + UNICODE_PROP_Changes_When_NFKC_Casefolded1, + UNICODE_PROP_ASCII_Hex_Digit, + UNICODE_PROP_Bidi_Control, + UNICODE_PROP_Dash, + UNICODE_PROP_Deprecated, + UNICODE_PROP_Diacritic, + UNICODE_PROP_Extender, + UNICODE_PROP_Hex_Digit, + UNICODE_PROP_IDS_Binary_Operator, + UNICODE_PROP_IDS_Trinary_Operator, + UNICODE_PROP_Ideographic, + UNICODE_PROP_Join_Control, + UNICODE_PROP_Logical_Order_Exception, + UNICODE_PROP_Noncharacter_Code_Point, + UNICODE_PROP_Pattern_Syntax, + UNICODE_PROP_Pattern_White_Space, + UNICODE_PROP_Quotation_Mark, + UNICODE_PROP_Radical, + UNICODE_PROP_Regional_Indicator, + UNICODE_PROP_Sentence_Terminal, + UNICODE_PROP_Soft_Dotted, + UNICODE_PROP_Terminal_Punctuation, + UNICODE_PROP_Unified_Ideograph, + UNICODE_PROP_Variation_Selector, + UNICODE_PROP_White_Space, + UNICODE_PROP_Bidi_Mirrored, + UNICODE_PROP_Emoji, + UNICODE_PROP_Emoji_Component, + UNICODE_PROP_Emoji_Modifier, + UNICODE_PROP_Emoji_Modifier_Base, + UNICODE_PROP_Emoji_Presentation, + UNICODE_PROP_Extended_Pictographic, + UNICODE_PROP_Default_Ignorable_Code_Point, + UNICODE_PROP_ID_Start, + UNICODE_PROP_Case_Ignorable, + UNICODE_PROP_ASCII, + UNICODE_PROP_Alphabetic, + UNICODE_PROP_Any, + UNICODE_PROP_Assigned, + UNICODE_PROP_Cased, + UNICODE_PROP_Changes_When_Casefolded, + UNICODE_PROP_Changes_When_Casemapped, + UNICODE_PROP_Changes_When_Lowercased, + UNICODE_PROP_Changes_When_NFKC_Casefolded, + UNICODE_PROP_Changes_When_Titlecased, + UNICODE_PROP_Changes_When_Uppercased, + UNICODE_PROP_Grapheme_Base, + UNICODE_PROP_Grapheme_Extend, + UNICODE_PROP_ID_Continue, + UNICODE_PROP_Lowercase, + UNICODE_PROP_Math, + UNICODE_PROP_Uppercase, + UNICODE_PROP_XID_Continue, + UNICODE_PROP_XID_Start, + UNICODE_PROP_Cased1, + UNICODE_PROP_COUNT, +} UnicodePropertyEnum; + +static const char unicode_prop_name_table[] = + "ASCII_Hex_Digit,AHex" "\0" + "Bidi_Control,Bidi_C" "\0" + "Dash" "\0" + "Deprecated,Dep" "\0" + "Diacritic,Dia" "\0" + "Extender,Ext" "\0" + "Hex_Digit,Hex" "\0" + "IDS_Binary_Operator,IDSB" "\0" + "IDS_Trinary_Operator,IDST" "\0" + "Ideographic,Ideo" "\0" + "Join_Control,Join_C" "\0" + "Logical_Order_Exception,LOE" "\0" + "Noncharacter_Code_Point,NChar" "\0" + "Pattern_Syntax,Pat_Syn" "\0" + "Pattern_White_Space,Pat_WS" "\0" + "Quotation_Mark,QMark" "\0" + "Radical" "\0" + "Regional_Indicator,RI" "\0" + "Sentence_Terminal,STerm" "\0" + "Soft_Dotted,SD" "\0" + "Terminal_Punctuation,Term" "\0" + "Unified_Ideograph,UIdeo" "\0" + "Variation_Selector,VS" "\0" + "White_Space,space" "\0" + "Bidi_Mirrored,Bidi_M" "\0" + "Emoji" "\0" + "Emoji_Component,EComp" "\0" + "Emoji_Modifier,EMod" "\0" + "Emoji_Modifier_Base,EBase" "\0" + "Emoji_Presentation,EPres" "\0" + "Extended_Pictographic,ExtPict" "\0" + "Default_Ignorable_Code_Point,DI" "\0" + "ID_Start,IDS" "\0" + "Case_Ignorable,CI" "\0" + "ASCII" "\0" + "Alphabetic,Alpha" "\0" + "Any" "\0" + "Assigned" "\0" + "Cased" "\0" + "Changes_When_Casefolded,CWCF" "\0" + "Changes_When_Casemapped,CWCM" "\0" + "Changes_When_Lowercased,CWL" "\0" + "Changes_When_NFKC_Casefolded,CWKCF" "\0" + "Changes_When_Titlecased,CWT" "\0" + "Changes_When_Uppercased,CWU" "\0" + "Grapheme_Base,Gr_Base" "\0" + "Grapheme_Extend,Gr_Ext" "\0" + "ID_Continue,IDC" "\0" + "Lowercase,Lower" "\0" + "Math" "\0" + "Uppercase,Upper" "\0" + "XID_Continue,XIDC" "\0" + "XID_Start,XIDS" "\0" +; + +static const uint8_t * const unicode_prop_table[] = { + unicode_prop_Hyphen_table, + unicode_prop_Other_Math_table, + unicode_prop_Other_Alphabetic_table, + unicode_prop_Other_Lowercase_table, + unicode_prop_Other_Uppercase_table, + unicode_prop_Other_Grapheme_Extend_table, + unicode_prop_Other_Default_Ignorable_Code_Point_table, + unicode_prop_Other_ID_Start_table, + unicode_prop_Other_ID_Continue_table, + unicode_prop_Prepended_Concatenation_Mark_table, + unicode_prop_ID_Continue1_table, + unicode_prop_XID_Start1_table, + unicode_prop_XID_Continue1_table, + unicode_prop_Changes_When_Titlecased1_table, + unicode_prop_Changes_When_Casefolded1_table, + unicode_prop_Changes_When_NFKC_Casefolded1_table, + unicode_prop_ASCII_Hex_Digit_table, + unicode_prop_Bidi_Control_table, + unicode_prop_Dash_table, + unicode_prop_Deprecated_table, + unicode_prop_Diacritic_table, + unicode_prop_Extender_table, + unicode_prop_Hex_Digit_table, + unicode_prop_IDS_Binary_Operator_table, + unicode_prop_IDS_Trinary_Operator_table, + unicode_prop_Ideographic_table, + unicode_prop_Join_Control_table, + unicode_prop_Logical_Order_Exception_table, + unicode_prop_Noncharacter_Code_Point_table, + unicode_prop_Pattern_Syntax_table, + unicode_prop_Pattern_White_Space_table, + unicode_prop_Quotation_Mark_table, + unicode_prop_Radical_table, + unicode_prop_Regional_Indicator_table, + unicode_prop_Sentence_Terminal_table, + unicode_prop_Soft_Dotted_table, + unicode_prop_Terminal_Punctuation_table, + unicode_prop_Unified_Ideograph_table, + unicode_prop_Variation_Selector_table, + unicode_prop_White_Space_table, + unicode_prop_Bidi_Mirrored_table, + unicode_prop_Emoji_table, + unicode_prop_Emoji_Component_table, + unicode_prop_Emoji_Modifier_table, + unicode_prop_Emoji_Modifier_Base_table, + unicode_prop_Emoji_Presentation_table, + unicode_prop_Extended_Pictographic_table, + unicode_prop_Default_Ignorable_Code_Point_table, + unicode_prop_ID_Start_table, + unicode_prop_Case_Ignorable_table, +}; + +static const uint16_t unicode_prop_len_table[] = { + countof(unicode_prop_Hyphen_table), + countof(unicode_prop_Other_Math_table), + countof(unicode_prop_Other_Alphabetic_table), + countof(unicode_prop_Other_Lowercase_table), + countof(unicode_prop_Other_Uppercase_table), + countof(unicode_prop_Other_Grapheme_Extend_table), + countof(unicode_prop_Other_Default_Ignorable_Code_Point_table), + countof(unicode_prop_Other_ID_Start_table), + countof(unicode_prop_Other_ID_Continue_table), + countof(unicode_prop_Prepended_Concatenation_Mark_table), + countof(unicode_prop_ID_Continue1_table), + countof(unicode_prop_XID_Start1_table), + countof(unicode_prop_XID_Continue1_table), + countof(unicode_prop_Changes_When_Titlecased1_table), + countof(unicode_prop_Changes_When_Casefolded1_table), + countof(unicode_prop_Changes_When_NFKC_Casefolded1_table), + countof(unicode_prop_ASCII_Hex_Digit_table), + countof(unicode_prop_Bidi_Control_table), + countof(unicode_prop_Dash_table), + countof(unicode_prop_Deprecated_table), + countof(unicode_prop_Diacritic_table), + countof(unicode_prop_Extender_table), + countof(unicode_prop_Hex_Digit_table), + countof(unicode_prop_IDS_Binary_Operator_table), + countof(unicode_prop_IDS_Trinary_Operator_table), + countof(unicode_prop_Ideographic_table), + countof(unicode_prop_Join_Control_table), + countof(unicode_prop_Logical_Order_Exception_table), + countof(unicode_prop_Noncharacter_Code_Point_table), + countof(unicode_prop_Pattern_Syntax_table), + countof(unicode_prop_Pattern_White_Space_table), + countof(unicode_prop_Quotation_Mark_table), + countof(unicode_prop_Radical_table), + countof(unicode_prop_Regional_Indicator_table), + countof(unicode_prop_Sentence_Terminal_table), + countof(unicode_prop_Soft_Dotted_table), + countof(unicode_prop_Terminal_Punctuation_table), + countof(unicode_prop_Unified_Ideograph_table), + countof(unicode_prop_Variation_Selector_table), + countof(unicode_prop_White_Space_table), + countof(unicode_prop_Bidi_Mirrored_table), + countof(unicode_prop_Emoji_table), + countof(unicode_prop_Emoji_Component_table), + countof(unicode_prop_Emoji_Modifier_table), + countof(unicode_prop_Emoji_Modifier_Base_table), + countof(unicode_prop_Emoji_Presentation_table), + countof(unicode_prop_Extended_Pictographic_table), + countof(unicode_prop_Default_Ignorable_Code_Point_table), + countof(unicode_prop_ID_Start_table), + countof(unicode_prop_Case_Ignorable_table), +}; + +#endif /* CONFIG_ALL_UNICODE */ diff --git a/libunicode.c b/libunicode.c new file mode 100644 index 0000000..6f3bd74 --- /dev/null +++ b/libunicode.c @@ -0,0 +1,1557 @@ +/* + * Unicode utilities + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * 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. + */ +#include +#include +#include +#include +#include + +#include "cutils.h" +#include "libunicode.h" +#include "libunicode-table.h" + +enum { + RUN_TYPE_U, + RUN_TYPE_L, + RUN_TYPE_UF, + RUN_TYPE_LF, + RUN_TYPE_UL, + RUN_TYPE_LSU, + RUN_TYPE_U2L_399_EXT2, + RUN_TYPE_UF_D20, + RUN_TYPE_UF_D1_EXT, + RUN_TYPE_U_EXT, + RUN_TYPE_LF_EXT, + RUN_TYPE_U_EXT2, + RUN_TYPE_L_EXT2, + RUN_TYPE_U_EXT3, +}; + +/* conv_type: + 0 = to upper + 1 = to lower + 2 = case folding (= to lower with modifications) +*/ +int lre_case_conv(uint32_t *res, uint32_t c, int conv_type) +{ + if (c < 128) { + if (conv_type) { + if (c >= 'A' && c <= 'Z') { + c = c - 'A' + 'a'; + } + } else { + if (c >= 'a' && c <= 'z') { + c = c - 'a' + 'A'; + } + } + } else { + uint32_t v, code, data, type, len, a, is_lower; + int idx, idx_min, idx_max; + + is_lower = (conv_type != 0); + idx_min = 0; + idx_max = countof(case_conv_table1) - 1; + while (idx_min <= idx_max) { + idx = (unsigned)(idx_max + idx_min) / 2; + v = case_conv_table1[idx]; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + if (c < code) { + idx_max = idx - 1; + } else if (c >= code + len) { + idx_min = idx + 1; + } else { + type = (v >> (32 - 17 - 7 - 4)) & 0xf; + data = ((v & 0xf) << 8) | case_conv_table2[idx]; + switch(type) { + case RUN_TYPE_U: + case RUN_TYPE_L: + case RUN_TYPE_UF: + case RUN_TYPE_LF: + if (conv_type == (type & 1) || + (type >= RUN_TYPE_UF && conv_type == 2)) { + c = c - code + (case_conv_table1[data] >> (32 - 17)); + } + break; + case RUN_TYPE_UL: + a = c - code; + if ((a & 1) != (1 - is_lower)) + break; + c = (a ^ 1) + code; + break; + case RUN_TYPE_LSU: + a = c - code; + if (a == 1) { + c += 2 * is_lower - 1; + } else if (a == (1 - is_lower) * 2) { + c += (2 * is_lower - 1) * 2; + } + break; + case RUN_TYPE_U2L_399_EXT2: + if (!is_lower) { + res[0] = c - code + case_conv_ext[data >> 6]; + res[1] = 0x399; + return 2; + } else { + c = c - code + case_conv_ext[data & 0x3f]; + } + break; + case RUN_TYPE_UF_D20: + if (conv_type == 1) + break; + c = data + (conv_type == 2) * 0x20; + break; + case RUN_TYPE_UF_D1_EXT: + if (conv_type == 1) + break; + c = case_conv_ext[data] + (conv_type == 2); + break; + case RUN_TYPE_U_EXT: + case RUN_TYPE_LF_EXT: + if (is_lower != (type - RUN_TYPE_U_EXT)) + break; + c = case_conv_ext[data]; + break; + case RUN_TYPE_U_EXT2: + case RUN_TYPE_L_EXT2: + if ((uint32_t)conv_type != (type - RUN_TYPE_U_EXT2)) + break; + res[0] = c - code + case_conv_ext[data >> 6]; + res[1] = case_conv_ext[data & 0x3f]; + return 2; + default: + case RUN_TYPE_U_EXT3: + if (conv_type != 0) + break; + res[0] = case_conv_ext[data >> 8]; + res[1] = case_conv_ext[(data >> 4) & 0xf]; + res[2] = case_conv_ext[data & 0xf]; + return 3; + } + break; + } + } + } + res[0] = c; + return 1; +} + +static uint32_t get_le24(const uint8_t *ptr) +{ +#if defined(__x86__) || defined(__x86_64__) + return *(const uint16_t *)(const void *)ptr | (ptr[2] << 16); +#else + return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16); +#endif +} + +#define UNICODE_INDEX_BLOCK_LEN 32 + +/* return -1 if not in table, otherwise the offset in the block */ +static int get_index_pos(uint32_t *pcode, uint32_t c, + const uint8_t *index_table, int index_table_len) +{ + uint32_t code, v; + int idx_min, idx_max, idx; + + idx_min = 0; + v = get_le24(index_table); + code = v & ((1 << 21) - 1); + if (c < code) { + *pcode = 0; + return 0; + } + idx_max = index_table_len - 1; + code = get_le24(index_table + idx_max * 3); + if (c >= code) + return -1; + /* invariant: tab[idx_min] <= c < tab2[idx_max] */ + while ((idx_max - idx_min) > 1) { + idx = (idx_max + idx_min) / 2; + v = get_le24(index_table + idx * 3); + code = v & ((1 << 21) - 1); + if (c < code) { + idx_max = idx; + } else { + idx_min = idx; + } + } + v = get_le24(index_table + idx_min * 3); + *pcode = v & ((1 << 21) - 1); + return (idx_min + 1) * UNICODE_INDEX_BLOCK_LEN + (v >> 21); +} + +static BOOL lre_is_in_table(uint32_t c, const uint8_t *table, + const uint8_t *index_table, int index_table_len) +{ + uint32_t code, b, bit; + int pos; + const uint8_t *p; + + pos = get_index_pos(&code, c, index_table, index_table_len); + if (pos < 0) + return FALSE; /* outside the table */ + p = table + pos; + bit = 0; + for(;;) { + b = *p++; + if (b < 64) { + code += (b >> 3) + 1; + if (c < code) + return bit; + bit ^= 1; + code += (b & 7) + 1; + } else if (b >= 0x80) { + code += b - 0x80 + 1; + } else if (b < 0x60) { + code += (((b - 0x40) << 8) | p[0]) + 1; + p++; + } else { + code += (((b - 0x60) << 16) | (p[0] << 8) | p[1]) + 1; + p += 2; + } + if (c < code) + return bit; + bit ^= 1; + } +} + +BOOL lre_is_cased(uint32_t c) +{ + uint32_t v, code, len; + int idx, idx_min, idx_max; + + idx_min = 0; + idx_max = countof(case_conv_table1) - 1; + while (idx_min <= idx_max) { + idx = (unsigned)(idx_max + idx_min) / 2; + v = case_conv_table1[idx]; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + if (c < code) { + idx_max = idx - 1; + } else if (c >= code + len) { + idx_min = idx + 1; + } else { + return TRUE; + } + } + return lre_is_in_table(c, unicode_prop_Cased1_table, + unicode_prop_Cased1_index, + sizeof(unicode_prop_Cased1_index) / 3); +} + +BOOL lre_is_case_ignorable(uint32_t c) +{ + return lre_is_in_table(c, unicode_prop_Case_Ignorable_table, + unicode_prop_Case_Ignorable_index, + sizeof(unicode_prop_Case_Ignorable_index) / 3); +} + +/* character range */ + +static __maybe_unused void cr_dump(CharRange *cr) +{ + int i; + for(i = 0; i < cr->len; i++) + printf("%d: 0x%04x\n", i, cr->points[i]); +} + +static void *cr_default_realloc(void *opaque, void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +void cr_init(CharRange *cr, void *mem_opaque, DynBufReallocFunc *realloc_func) +{ + cr->len = cr->size = 0; + cr->points = NULL; + cr->mem_opaque = mem_opaque; + cr->realloc_func = realloc_func ? realloc_func : cr_default_realloc; +} + +void cr_free(CharRange *cr) +{ + cr->realloc_func(cr->mem_opaque, cr->points, 0); +} + +int cr_realloc(CharRange *cr, int size) +{ + int new_size; + uint32_t *new_buf; + + if (size > cr->size) { + new_size = max_int(size, cr->size * 3 / 2); + new_buf = cr->realloc_func(cr->mem_opaque, cr->points, + new_size * sizeof(cr->points[0])); + if (!new_buf) + return -1; + cr->points = new_buf; + cr->size = new_size; + } + return 0; +} + +int cr_copy(CharRange *cr, const CharRange *cr1) +{ + if (cr_realloc(cr, cr1->len)) + return -1; + memcpy(cr->points, cr1->points, sizeof(cr->points[0]) * cr1->len); + cr->len = cr1->len; + return 0; +} + +/* merge consecutive intervals and remove empty intervals */ +static void cr_compress(CharRange *cr) +{ + int i, j, k, len; + uint32_t *pt; + + pt = cr->points; + len = cr->len; + i = 0; + j = 0; + k = 0; + while ((i + 1) < len) { + if (pt[i] == pt[i + 1]) { + /* empty interval */ + i += 2; + } else { + j = i; + while ((j + 3) < len && pt[j + 1] == pt[j + 2]) + j += 2; + /* just copy */ + pt[k] = pt[i]; + pt[k + 1] = pt[j + 1]; + k += 2; + i = j + 2; + } + } + cr->len = k; +} + +/* union or intersection */ +int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, + const uint32_t *b_pt, int b_len, int op) +{ + int a_idx, b_idx, is_in; + uint32_t v; + + a_idx = 0; + b_idx = 0; + for(;;) { + /* get one more point from a or b in increasing order */ + if (a_idx < a_len && b_idx < b_len) { + if (a_pt[a_idx] < b_pt[b_idx]) { + goto a_add; + } else if (a_pt[a_idx] == b_pt[b_idx]) { + v = a_pt[a_idx]; + a_idx++; + b_idx++; + } else { + goto b_add; + } + } else if (a_idx < a_len) { + a_add: + v = a_pt[a_idx++]; + } else if (b_idx < b_len) { + b_add: + v = b_pt[b_idx++]; + } else { + break; + } + /* add the point if the in/out status changes */ + switch(op) { + case CR_OP_UNION: + is_in = (a_idx & 1) | (b_idx & 1); + break; + case CR_OP_INTER: + is_in = (a_idx & 1) & (b_idx & 1); + break; + case CR_OP_XOR: + is_in = (a_idx & 1) ^ (b_idx & 1); + break; + default: + abort(); + } + if (is_in != (cr->len & 1)) { + if (cr_add_point(cr, v)) + return -1; + } + } + cr_compress(cr); + return 0; +} + +int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len) +{ + CharRange a = *cr; + int ret; + cr->len = 0; + cr->size = 0; + cr->points = NULL; + ret = cr_op(cr, a.points, a.len, b_pt, b_len, CR_OP_UNION); + cr_free(&a); + return ret; +} + +int cr_invert(CharRange *cr) +{ + int len; + len = cr->len; + if (cr_realloc(cr, len + 2)) + return -1; + memmove(cr->points + 1, cr->points, len * sizeof(cr->points[0])); + cr->points[0] = 0; + cr->points[len + 1] = UINT32_MAX; + cr->len = len + 2; + cr_compress(cr); + return 0; +} + +#ifdef CONFIG_ALL_UNICODE + +BOOL lre_is_id_start(uint32_t c) +{ + return lre_is_in_table(c, unicode_prop_ID_Start_table, + unicode_prop_ID_Start_index, + sizeof(unicode_prop_ID_Start_index) / 3); +} + +BOOL lre_is_id_continue(uint32_t c) +{ + return lre_is_id_start(c) || + lre_is_in_table(c, unicode_prop_ID_Continue1_table, + unicode_prop_ID_Continue1_index, + sizeof(unicode_prop_ID_Continue1_index) / 3); +} + +#define UNICODE_DECOMP_LEN_MAX 18 + +typedef enum { + DECOMP_TYPE_C1, /* 16 bit char */ + DECOMP_TYPE_L1, /* 16 bit char table */ + DECOMP_TYPE_L2, + DECOMP_TYPE_L3, + DECOMP_TYPE_L4, + DECOMP_TYPE_L5, /* XXX: not used */ + DECOMP_TYPE_L6, /* XXX: could remove */ + DECOMP_TYPE_L7, /* XXX: could remove */ + DECOMP_TYPE_LL1, /* 18 bit char table */ + DECOMP_TYPE_LL2, + DECOMP_TYPE_S1, /* 8 bit char table */ + DECOMP_TYPE_S2, + DECOMP_TYPE_S3, + DECOMP_TYPE_S4, + DECOMP_TYPE_S5, + DECOMP_TYPE_I1, /* increment 16 bit char value */ + DECOMP_TYPE_I2_0, + DECOMP_TYPE_I2_1, + DECOMP_TYPE_I3_1, + DECOMP_TYPE_I3_2, + DECOMP_TYPE_I4_1, + DECOMP_TYPE_I4_2, + DECOMP_TYPE_B1, /* 16 bit base + 8 bit offset */ + DECOMP_TYPE_B2, + DECOMP_TYPE_B3, + DECOMP_TYPE_B4, + DECOMP_TYPE_B5, + DECOMP_TYPE_B6, + DECOMP_TYPE_B7, + DECOMP_TYPE_B8, + DECOMP_TYPE_B18, + DECOMP_TYPE_LS2, + DECOMP_TYPE_PAT3, + DECOMP_TYPE_S2_UL, + DECOMP_TYPE_LS2_UL, +} DecompTypeEnum; + +static uint32_t unicode_get_short_code(uint32_t c) +{ + static const uint16_t unicode_short_table[2] = { 0x2044, 0x2215 }; + + if (c < 0x80) + return c; + else if (c < 0x80 + 0x50) + return c - 0x80 + 0x300; + else + return unicode_short_table[c - 0x80 - 0x50]; +} + +static uint32_t unicode_get_lower_simple(uint32_t c) +{ + if (c < 0x100 || (c >= 0x410 && c <= 0x42f)) + c += 0x20; + else + c++; + return c; +} + +static uint16_t unicode_get16(const uint8_t *p) +{ + return p[0] | (p[1] << 8); +} + +static int unicode_decomp_entry(uint32_t *res, uint32_t c, + int idx, uint32_t code, uint32_t len, + uint32_t type) +{ + uint32_t c1; + int l, i, p; + const uint8_t *d; + + if (type == DECOMP_TYPE_C1) { + res[0] = unicode_decomp_table2[idx]; + return 1; + } else { + d = unicode_decomp_data + unicode_decomp_table2[idx]; + switch(type) { + case DECOMP_TYPE_L1: + case DECOMP_TYPE_L2: + case DECOMP_TYPE_L3: + case DECOMP_TYPE_L4: + case DECOMP_TYPE_L5: + case DECOMP_TYPE_L6: + case DECOMP_TYPE_L7: + l = type - DECOMP_TYPE_L1 + 1; + d += (c - code) * l * 2; + for(i = 0; i < l; i++) { + if ((res[i] = unicode_get16(d + 2 * i)) == 0) + return 0; + } + return l; + case DECOMP_TYPE_LL1: + case DECOMP_TYPE_LL2: + { + uint32_t k, p1; + l = type - DECOMP_TYPE_LL1 + 1; + k = (c - code) * l; + p1 = len * l * 2; + for(i = 0; i < l; i++) { + c1 = unicode_get16(d + 2 * k) | + (((d[p1 + (k / 4)] >> ((k % 4) * 2)) & 3) << 16); + if (!c1) + return 0; + res[i] = c1; + k++; + } + } + return l; + case DECOMP_TYPE_S1: + case DECOMP_TYPE_S2: + case DECOMP_TYPE_S3: + case DECOMP_TYPE_S4: + case DECOMP_TYPE_S5: + l = type - DECOMP_TYPE_S1 + 1; + d += (c - code) * l; + for(i = 0; i < l; i++) { + if ((res[i] = unicode_get_short_code(d[i])) == 0) + return 0; + } + return l; + case DECOMP_TYPE_I1: + l = 1; + p = 0; + goto decomp_type_i; + case DECOMP_TYPE_I2_0: + case DECOMP_TYPE_I2_1: + case DECOMP_TYPE_I3_1: + case DECOMP_TYPE_I3_2: + case DECOMP_TYPE_I4_1: + case DECOMP_TYPE_I4_2: + l = 2 + ((type - DECOMP_TYPE_I2_0) >> 1); + p = ((type - DECOMP_TYPE_I2_0) & 1) + (l > 2); + decomp_type_i: + for(i = 0; i < l; i++) { + c1 = unicode_get16(d + 2 * i); + if (i == p) + c1 += c - code; + res[i] = c1; + } + return l; + case DECOMP_TYPE_B18: + l = 18; + goto decomp_type_b; + case DECOMP_TYPE_B1: + case DECOMP_TYPE_B2: + case DECOMP_TYPE_B3: + case DECOMP_TYPE_B4: + case DECOMP_TYPE_B5: + case DECOMP_TYPE_B6: + case DECOMP_TYPE_B7: + case DECOMP_TYPE_B8: + l = type - DECOMP_TYPE_B1 + 1; + decomp_type_b: + { + uint32_t c_min; + c_min = unicode_get16(d); + d += 2 + (c - code) * l; + for(i = 0; i < l; i++) { + c1 = d[i]; + if (c1 == 0xff) + c1 = 0x20; + else + c1 += c_min; + res[i] = c1; + } + } + return l; + case DECOMP_TYPE_LS2: + d += (c - code) * 3; + if (!(res[0] = unicode_get16(d))) + return 0; + res[1] = unicode_get_short_code(d[2]); + return 2; + case DECOMP_TYPE_PAT3: + res[0] = unicode_get16(d); + res[2] = unicode_get16(d + 2); + d += 4 + (c - code) * 2; + res[1] = unicode_get16(d); + return 3; + case DECOMP_TYPE_S2_UL: + case DECOMP_TYPE_LS2_UL: + c1 = c - code; + if (type == DECOMP_TYPE_S2_UL) { + d += c1 & ~1; + c = unicode_get_short_code(*d); + d++; + } else { + d += (c1 >> 1) * 3; + c = unicode_get16(d); + d += 2; + } + if (c1 & 1) + c = unicode_get_lower_simple(c); + res[0] = c; + res[1] = unicode_get_short_code(*d); + return 2; + } + } + return 0; +} + + +/* return the length of the decomposition (length <= + UNICODE_DECOMP_LEN_MAX) or 0 if no decomposition */ +static int unicode_decomp_char(uint32_t *res, uint32_t c, BOOL is_compat1) +{ + uint32_t v, type, code, len; + int idx_min, idx_max, idx; + BOOL is_compat; + + idx_min = 0; + idx_max = countof(unicode_decomp_table1) - 1; + while (idx_min <= idx_max) { + idx = (idx_max + idx_min) / 2; + v = unicode_decomp_table1[idx]; + code = v >> (32 - 18); + len = (v >> (32 - 18 - 7)) & 0x7f; + // printf("idx=%d code=%05x len=%d\n", idx, code, len); + if (c < code) { + idx_max = idx - 1; + } else if (c >= code + len) { + idx_min = idx + 1; + } else { + is_compat = v & 1; + if (is_compat1 < is_compat) + break; + type = (v >> (32 - 18 - 7 - 6)) & 0x3f; + return unicode_decomp_entry(res, c, idx, code, len, type); + } + } + return 0; +} + +/* return 0 if no pair found */ +static int unicode_compose_pair(uint32_t c0, uint32_t c1) +{ + uint32_t code, len, type, v, idx1, d_idx, d_offset, ch; + int idx_min, idx_max, idx, d; + uint32_t pair[2]; + + idx_min = 0; + idx_max = countof(unicode_comp_table) - 1; + while (idx_min <= idx_max) { + idx = (idx_max + idx_min) / 2; + idx1 = unicode_comp_table[idx]; + + /* idx1 represent an entry of the decomposition table */ + d_idx = idx1 >> 6; + d_offset = idx1 & 0x3f; + v = unicode_decomp_table1[d_idx]; + code = v >> (32 - 18); + len = (v >> (32 - 18 - 7)) & 0x7f; + type = (v >> (32 - 18 - 7 - 6)) & 0x3f; + ch = code + d_offset; + unicode_decomp_entry(pair, ch, d_idx, code, len, type); + d = c0 - pair[0]; + if (d == 0) + d = c1 - pair[1]; + if (d < 0) { + idx_max = idx - 1; + } else if (d > 0) { + idx_min = idx + 1; + } else { + return ch; + } + } + return 0; +} + +/* return the combining class of character c (between 0 and 255) */ +static int unicode_get_cc(uint32_t c) +{ + uint32_t code, n, type, cc, c1, b; + int pos; + const uint8_t *p; + + pos = get_index_pos(&code, c, + unicode_cc_index, sizeof(unicode_cc_index) / 3); + if (pos < 0) + return 0; + p = unicode_cc_table + pos; + for(;;) { + b = *p++; + type = b >> 6; + n = b & 0x3f; + if (n < 48) { + } else if (n < 56) { + n = (n - 48) << 8; + n |= *p++; + n += 48; + } else { + n = (n - 56) << 8; + n |= *p++ << 8; + n |= *p++; + n += 48 + (1 << 11); + } + if (type <= 1) + p++; + c1 = code + n + 1; + if (c < c1) { + switch(type) { + case 0: + cc = p[-1]; + break; + case 1: + cc = p[-1] + c - code; + break; + case 2: + cc = 0; + break; + default: + case 3: + cc = 230; + break; + } + return cc; + } + code = c1; + } +} + +static void sort_cc(int *buf, int len) +{ + int i, j, k, cc, cc1, start, ch1; + + for(i = 0; i < len; i++) { + cc = unicode_get_cc(buf[i]); + if (cc != 0) { + start = i; + j = i + 1; + while (j < len) { + ch1 = buf[j]; + cc1 = unicode_get_cc(ch1); + if (cc1 == 0) + break; + k = j - 1; + while (k >= start) { + if (unicode_get_cc(buf[k]) <= cc1) + break; + buf[k + 1] = buf[k]; + k--; + } + buf[k + 1] = ch1; + j++; + } +#if 0 + printf("cc:"); + for(k = start; k < j; k++) { + printf(" %3d", unicode_get_cc(buf[k])); + } + printf("\n"); +#endif + i = j; + } + } +} + +static void to_nfd_rec(DynBuf *dbuf, + const int *src, int src_len, int is_compat) +{ + uint32_t c, v; + int i, l; + uint32_t res[UNICODE_DECOMP_LEN_MAX]; + + for(i = 0; i < src_len; i++) { + c = src[i]; + if (c >= 0xac00 && c < 0xd7a4) { + /* Hangul decomposition */ + c -= 0xac00; + dbuf_put_u32(dbuf, 0x1100 + c / 588); + dbuf_put_u32(dbuf, 0x1161 + (c % 588) / 28); + v = c % 28; + if (v != 0) + dbuf_put_u32(dbuf, 0x11a7 + v); + } else { + l = unicode_decomp_char(res, c, is_compat); + if (l) { + to_nfd_rec(dbuf, (int *)res, l, is_compat); + } else { + dbuf_put_u32(dbuf, c); + } + } + } +} + +/* return 0 if not found */ +static int compose_pair(uint32_t c0, uint32_t c1) +{ + /* Hangul composition */ + if (c0 >= 0x1100 && c0 < 0x1100 + 19 && + c1 >= 0x1161 && c1 < 0x1161 + 21) { + return 0xac00 + (c0 - 0x1100) * 588 + (c1 - 0x1161) * 28; + } else if (c0 >= 0xac00 && c0 < 0xac00 + 11172 && + (c0 - 0xac00) % 28 == 0 && + c1 >= 0x11a7 && c1 < 0x11a7 + 28) { + return c0 + c1 - 0x11a7; + } else { + return unicode_compose_pair(c0, c1); + } +} + +int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, + UnicodeNormalizationEnum n_type, + void *opaque, DynBufReallocFunc *realloc_func) +{ + int *buf, buf_len, i, p, starter_pos, cc, last_cc, out_len; + BOOL is_compat; + DynBuf dbuf_s, *dbuf = &dbuf_s; + + is_compat = n_type >> 1; + + dbuf_init2(dbuf, opaque, realloc_func); + if (dbuf_realloc(dbuf, sizeof(int) * src_len)) + goto fail; + + /* common case: latin1 is unaffected by NFC */ + if (n_type == UNICODE_NFC) { + for(i = 0; i < src_len; i++) { + if (src[i] >= 0x100) + goto not_latin1; + } + buf = (int *)(void *)dbuf->buf; + memcpy(buf, src, src_len * sizeof(int)); + *pdst = (uint32_t *)buf; + return src_len; + not_latin1: ; + } + + to_nfd_rec(dbuf, (const int *)src, src_len, is_compat); + if (dbuf_error(dbuf)) { + fail: + *pdst = NULL; + return -1; + } + buf = (int *)(void *)dbuf->buf; + buf_len = dbuf->size / sizeof(int); + + sort_cc(buf, buf_len); + + if (buf_len <= 1 || (n_type & 1) != 0) { + /* NFD / NFKD */ + *pdst = (uint32_t *)buf; + return buf_len; + } + + i = 1; + out_len = 1; + while (i < buf_len) { + /* find the starter character and test if it is blocked from + the character at 'i' */ + last_cc = unicode_get_cc(buf[i]); + starter_pos = out_len - 1; + while (starter_pos >= 0) { + cc = unicode_get_cc(buf[starter_pos]); + if (cc == 0) + break; + if (cc >= last_cc) + goto next; + last_cc = 256; + starter_pos--; + } + if (starter_pos >= 0 && + (p = compose_pair(buf[starter_pos], buf[i])) != 0) { + buf[starter_pos] = p; + i++; + } else { + next: + buf[out_len++] = buf[i++]; + } + } + *pdst = (uint32_t *)buf; + return out_len; +} + +/* char ranges for various unicode properties */ + +static int unicode_find_name(const char *name_table, const char *name) +{ + const char *p, *r; + int pos; + size_t name_len, len; + + p = name_table; + pos = 0; + name_len = strlen(name); + while (*p) { + for(;;) { + r = strchr(p, ','); + if (!r) + len = strlen(p); + else + len = r - p; + if (len == name_len && !memcmp(p, name, name_len)) + return pos; + p += len + 1; + if (!r) + break; + } + pos++; + } + return -1; +} + +/* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2 + if not found */ +int unicode_script(CharRange *cr, + const char *script_name, BOOL is_ext) +{ + int script_idx; + const uint8_t *p, *p_end; + uint32_t c, c1, b, n, v, v_len, i, type; + CharRange cr1_s, *cr1; + CharRange cr2_s, *cr2 = &cr2_s; + BOOL is_common; + + script_idx = unicode_find_name(unicode_script_name_table, script_name); + if (script_idx < 0) + return -2; + /* Note: we remove the "Unknown" Script */ + script_idx += UNICODE_SCRIPT_Unknown + 1; + + is_common = (script_idx == UNICODE_SCRIPT_Common || + script_idx == UNICODE_SCRIPT_Inherited); + if (is_ext) { + cr1 = &cr1_s; + cr_init(cr1, cr->mem_opaque, cr->realloc_func); + cr_init(cr2, cr->mem_opaque, cr->realloc_func); + } else { + cr1 = cr; + } + + p = unicode_script_table; + p_end = unicode_script_table + countof(unicode_script_table); + c = 0; + while (p < p_end) { + b = *p++; + type = b >> 7; + n = b & 0x7f; + if (n < 96) { + } else if (n < 112) { + n = (n - 96) << 8; + n |= *p++; + n += 96; + } else { + n = (n - 112) << 16; + n |= *p++ << 8; + n |= *p++; + n += 96 + (1 << 12); + } + if (type == 0) + v = 0; + else + v = *p++; + c1 = c + n + 1; + if (v == (uint32_t)script_idx) { + if (cr_add_interval(cr1, c, c1)) + goto fail; + } + c = c1; + } + + if (is_ext) { + /* add the script extensions */ + p = unicode_script_ext_table; + p_end = unicode_script_ext_table + countof(unicode_script_ext_table); + c = 0; + while (p < p_end) { + b = *p++; + if (b < 128) { + n = b; + } else if (b < 128 + 64) { + n = (b - 128) << 8; + n |= *p++; + n += 128; + } else { + n = (b - 128 - 64) << 16; + n |= *p++ << 8; + n |= *p++; + n += 128 + (1 << 14); + } + c1 = c + n + 1; + v_len = *p++; + if (is_common) { + if (v_len != 0) { + if (cr_add_interval(cr2, c, c1)) + goto fail; + } + } else { + for(i = 0; i < v_len; i++) { + if (p[i] == script_idx) { + if (cr_add_interval(cr2, c, c1)) + goto fail; + break; + } + } + } + p += v_len; + c = c1; + } + if (is_common) { + /* remove all the characters with script extensions */ + if (cr_invert(cr2)) + goto fail; + if (cr_op(cr, cr1->points, cr1->len, cr2->points, cr2->len, + CR_OP_INTER)) + goto fail; + } else { + if (cr_op(cr, cr1->points, cr1->len, cr2->points, cr2->len, + CR_OP_UNION)) + goto fail; + } + cr_free(cr1); + cr_free(cr2); + } + return 0; + fail: + if (is_ext) { + cr_free(cr1); + cr_free(cr2); + } + goto fail; +} + +#define M(id) (1U << UNICODE_GC_ ## id) + +static int unicode_general_category1(CharRange *cr, uint32_t gc_mask) +{ + const uint8_t *p, *p_end; + uint32_t c, c0, b, n, v; + + p = unicode_gc_table; + p_end = unicode_gc_table + countof(unicode_gc_table); + c = 0; + while (p < p_end) { + b = *p++; + n = b >> 5; + v = b & 0x1f; + if (n == 7) { + n = *p++; + if (n < 128) { + n += 7; + } else if (n < 128 + 64) { + n = (n - 128) << 8; + n |= *p++; + n += 7 + 128; + } else { + n = (n - 128 - 64) << 16; + n |= *p++ << 8; + n |= *p++; + n += 7 + 128 + (1 << 14); + } + } + c0 = c; + c += n + 1; + if (v == 31) { + /* run of Lu / Ll */ + b = gc_mask & (M(Lu) | M(Ll)); + if (b != 0) { + if (b == (M(Lu) | M(Ll))) { + goto add_range; + } else { + c0 += ((gc_mask & M(Ll)) != 0); + for(; c0 < c; c0 += 2) { + if (cr_add_interval(cr, c0, c0 + 1)) + return -1; + } + } + } + } else if ((gc_mask >> v) & 1) { + add_range: + if (cr_add_interval(cr, c0, c)) + return -1; + } + } + return 0; +} + +static int unicode_prop1(CharRange *cr, int prop_idx) +{ + const uint8_t *p, *p_end; + uint32_t c, c0, b, bit; + + p = unicode_prop_table[prop_idx]; + p_end = p + unicode_prop_len_table[prop_idx]; + c = 0; + bit = 0; + while (p < p_end) { + c0 = c; + b = *p++; + if (b < 64) { + c += (b >> 3) + 1; + if (bit) { + if (cr_add_interval(cr, c0, c)) + return -1; + } + bit ^= 1; + c0 = c; + c += (b & 7) + 1; + } else if (b >= 0x80) { + c += b - 0x80 + 1; + } else if (b < 0x60) { + c += (((b - 0x40) << 8) | p[0]) + 1; + p++; + } else { + c += (((b - 0x60) << 16) | (p[0] << 8) | p[1]) + 1; + p += 2; + } + if (bit) { + if (cr_add_interval(cr, c0, c)) + return -1; + } + bit ^= 1; + } + return 0; +} + +#define CASE_U (1 << 0) +#define CASE_L (1 << 1) +#define CASE_F (1 << 2) + +/* use the case conversion table to generate range of characters. + CASE_U: set char if modified by uppercasing, + CASE_L: set char if modified by lowercasing, + CASE_F: set char if modified by case folding, + */ +static int unicode_case1(CharRange *cr, int case_mask) +{ +#define MR(x) (1 << RUN_TYPE_ ## x) + const uint32_t tab_run_mask[3] = { + MR(U) | MR(UF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(UF_D20) | + MR(UF_D1_EXT) | MR(U_EXT) | MR(U_EXT2) | MR(U_EXT3), + + MR(L) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(L_EXT2), + + MR(UF) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(UF_D20) | MR(UF_D1_EXT) | MR(LF_EXT), + }; +#undef MR + uint32_t mask, v, code, type, len, i, idx; + + if (case_mask == 0) + return 0; + mask = 0; + for(i = 0; i < 3; i++) { + if ((case_mask >> i) & 1) + mask |= tab_run_mask[i]; + } + for(idx = 0; idx < countof(case_conv_table1); idx++) { + v = case_conv_table1[idx]; + type = (v >> (32 - 17 - 7 - 4)) & 0xf; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + if ((mask >> type) & 1) { + // printf("%d: type=%d %04x %04x\n", idx, type, code, code + len - 1); + switch(type) { + case RUN_TYPE_UL: + if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F))) + goto def_case; + code += ((case_mask & CASE_U) != 0); + for(i = 0; i < len; i += 2) { + if (cr_add_interval(cr, code + i, code + i + 1)) + return -1; + } + break; + case RUN_TYPE_LSU: + if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F))) + goto def_case; + if (!(case_mask & CASE_U)) { + if (cr_add_interval(cr, code, code + 1)) + return -1; + } + if (cr_add_interval(cr, code + 1, code + 2)) + return -1; + if (case_mask & CASE_U) { + if (cr_add_interval(cr, code + 2, code + 3)) + return -1; + } + break; + default: + def_case: + if (cr_add_interval(cr, code, code + len)) + return -1; + break; + } + } + } + return 0; +} + +typedef enum { + POP_GC, + POP_PROP, + POP_CASE, + POP_UNION, + POP_INTER, + POP_XOR, + POP_INVERT, + POP_END, +} PropOPEnum; + +#define POP_STACK_LEN_MAX 4 + +static int unicode_prop_ops(CharRange *cr, ...) +{ + va_list ap; + CharRange stack[POP_STACK_LEN_MAX]; + int stack_len, op, ret, i; + uint32_t a; + + va_start(ap, cr); + stack_len = 0; + for(;;) { + op = va_arg(ap, int); + switch(op) { + case POP_GC: + assert(stack_len < POP_STACK_LEN_MAX); + a = va_arg(ap, int); + cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func); + if (unicode_general_category1(&stack[stack_len - 1], a)) + goto fail; + break; + case POP_PROP: + assert(stack_len < POP_STACK_LEN_MAX); + a = va_arg(ap, int); + cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func); + if (unicode_prop1(&stack[stack_len - 1], a)) + goto fail; + break; + case POP_CASE: + assert(stack_len < POP_STACK_LEN_MAX); + a = va_arg(ap, int); + cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func); + if (unicode_case1(&stack[stack_len - 1], a)) + goto fail; + break; + case POP_UNION: + case POP_INTER: + case POP_XOR: + { + CharRange *cr1, *cr2, *cr3; + assert(stack_len >= 2); + assert(stack_len < POP_STACK_LEN_MAX); + cr1 = &stack[stack_len - 2]; + cr2 = &stack[stack_len - 1]; + cr3 = &stack[stack_len++]; + cr_init(cr3, cr->mem_opaque, cr->realloc_func); + if (cr_op(cr3, cr1->points, cr1->len, + cr2->points, cr2->len, op - POP_UNION + CR_OP_UNION)) + goto fail; + cr_free(cr1); + cr_free(cr2); + *cr1 = *cr3; + stack_len -= 2; + } + break; + case POP_INVERT: + assert(stack_len >= 1); + if (cr_invert(&stack[stack_len - 1])) + goto fail; + break; + case POP_END: + goto done; + default: + abort(); + } + } + done: + assert(stack_len == 1); + ret = cr_copy(cr, &stack[0]); + cr_free(&stack[0]); + return ret; + fail: + for(i = 0; i < stack_len; i++) + cr_free(&stack[i]); + return -1; +} + +static const uint32_t unicode_gc_mask_table[] = { + M(Lu) | M(Ll) | M(Lt), /* LC */ + M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo), /* L */ + M(Mn) | M(Mc) | M(Me), /* M */ + M(Nd) | M(Nl) | M(No), /* N */ + M(Sm) | M(Sc) | M(Sk) | M(So), /* S */ + M(Pc) | M(Pd) | M(Ps) | M(Pe) | M(Pi) | M(Pf) | M(Po), /* P */ + M(Zs) | M(Zl) | M(Zp), /* Z */ + M(Cc) | M(Cf) | M(Cs) | M(Co) | M(Cn), /* C */ +}; + +/* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2 + if not found */ +int unicode_general_category(CharRange *cr, const char *gc_name) +{ + int gc_idx; + uint32_t gc_mask; + + gc_idx = unicode_find_name(unicode_gc_name_table, gc_name); + if (gc_idx < 0) + return -2; + if (gc_idx <= UNICODE_GC_Co) { + gc_mask = (uint64_t)1 << gc_idx; + } else { + gc_mask = unicode_gc_mask_table[gc_idx - UNICODE_GC_LC]; + } + return unicode_general_category1(cr, gc_mask); +} + + +/* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2 + if not found */ +int unicode_prop(CharRange *cr, const char *prop_name) +{ + int prop_idx, ret; + + prop_idx = unicode_find_name(unicode_prop_name_table, prop_name); + if (prop_idx < 0) + return -2; + prop_idx += UNICODE_PROP_ASCII_Hex_Digit; + + ret = 0; + switch(prop_idx) { + case UNICODE_PROP_ASCII: + if (cr_add_interval(cr, 0x00, 0x7f + 1)) + return -1; + break; + case UNICODE_PROP_Any: + if (cr_add_interval(cr, 0x00000, 0x10ffff + 1)) + return -1; + break; + case UNICODE_PROP_Assigned: + ret = unicode_prop_ops(cr, + POP_GC, M(Cn), + POP_INVERT, + POP_END); + break; + case UNICODE_PROP_Math: + ret = unicode_prop_ops(cr, + POP_GC, M(Sm), + POP_PROP, UNICODE_PROP_Other_Math, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_Lowercase: + ret = unicode_prop_ops(cr, + POP_GC, M(Ll), + POP_PROP, UNICODE_PROP_Other_Lowercase, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_Uppercase: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu), + POP_PROP, UNICODE_PROP_Other_Uppercase, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_Cased: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu) | M(Ll) | M(Lt), + POP_PROP, UNICODE_PROP_Other_Uppercase, + POP_UNION, + POP_PROP, UNICODE_PROP_Other_Lowercase, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_Alphabetic: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl), + POP_PROP, UNICODE_PROP_Other_Uppercase, + POP_UNION, + POP_PROP, UNICODE_PROP_Other_Lowercase, + POP_UNION, + POP_PROP, UNICODE_PROP_Other_Alphabetic, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_Grapheme_Base: + ret = unicode_prop_ops(cr, + POP_GC, M(Cc) | M(Cf) | M(Cs) | M(Co) | M(Cn) | M(Zl) | M(Zp) | M(Me) | M(Mn), + POP_PROP, UNICODE_PROP_Other_Grapheme_Extend, + POP_UNION, + POP_INVERT, + POP_END); + break; + case UNICODE_PROP_Grapheme_Extend: + ret = unicode_prop_ops(cr, + POP_GC, M(Me) | M(Mn), + POP_PROP, UNICODE_PROP_Other_Grapheme_Extend, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_XID_Start: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl), + POP_PROP, UNICODE_PROP_Other_ID_Start, + POP_UNION, + POP_PROP, UNICODE_PROP_Pattern_Syntax, + POP_PROP, UNICODE_PROP_Pattern_White_Space, + POP_UNION, + POP_PROP, UNICODE_PROP_XID_Start1, + POP_UNION, + POP_INVERT, + POP_INTER, + POP_END); + break; + case UNICODE_PROP_XID_Continue: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl) | + M(Mn) | M(Mc) | M(Nd) | M(Pc), + POP_PROP, UNICODE_PROP_Other_ID_Start, + POP_UNION, + POP_PROP, UNICODE_PROP_Other_ID_Continue, + POP_UNION, + POP_PROP, UNICODE_PROP_Pattern_Syntax, + POP_PROP, UNICODE_PROP_Pattern_White_Space, + POP_UNION, + POP_PROP, UNICODE_PROP_XID_Continue1, + POP_UNION, + POP_INVERT, + POP_INTER, + POP_END); + break; + case UNICODE_PROP_Changes_When_Uppercased: + ret = unicode_case1(cr, CASE_U); + break; + case UNICODE_PROP_Changes_When_Lowercased: + ret = unicode_case1(cr, CASE_L); + break; + case UNICODE_PROP_Changes_When_Casemapped: + ret = unicode_case1(cr, CASE_U | CASE_L | CASE_F); + break; + case UNICODE_PROP_Changes_When_Titlecased: + ret = unicode_prop_ops(cr, + POP_CASE, CASE_U, + POP_PROP, UNICODE_PROP_Changes_When_Titlecased1, + POP_XOR, + POP_END); + break; + case UNICODE_PROP_Changes_When_Casefolded: + ret = unicode_prop_ops(cr, + POP_CASE, CASE_F, + POP_PROP, UNICODE_PROP_Changes_When_Casefolded1, + POP_XOR, + POP_END); + break; + case UNICODE_PROP_Changes_When_NFKC_Casefolded: + ret = unicode_prop_ops(cr, + POP_CASE, CASE_F, + POP_PROP, UNICODE_PROP_Changes_When_NFKC_Casefolded1, + POP_XOR, + POP_END); + break; +#if 0 + case UNICODE_PROP_ID_Start: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl), + POP_PROP, UNICODE_PROP_Other_ID_Start, + POP_UNION, + POP_PROP, UNICODE_PROP_Pattern_Syntax, + POP_PROP, UNICODE_PROP_Pattern_White_Space, + POP_UNION, + POP_INVERT, + POP_INTER, + POP_END); + break; + case UNICODE_PROP_ID_Continue: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl) | + M(Mn) | M(Mc) | M(Nd) | M(Pc), + POP_PROP, UNICODE_PROP_Other_ID_Start, + POP_UNION, + POP_PROP, UNICODE_PROP_Other_ID_Continue, + POP_UNION, + POP_PROP, UNICODE_PROP_Pattern_Syntax, + POP_PROP, UNICODE_PROP_Pattern_White_Space, + POP_UNION, + POP_INVERT, + POP_INTER, + POP_END); + break; + case UNICODE_PROP_Case_Ignorable: + ret = unicode_prop_ops(cr, + POP_GC, M(Mn) | M(Cf) | M(Lm) | M(Sk), + POP_PROP, UNICODE_PROP_Case_Ignorable1, + POP_XOR, + POP_END); + break; +#else + /* we use the existing tables */ + case UNICODE_PROP_ID_Continue: + ret = unicode_prop_ops(cr, + POP_PROP, UNICODE_PROP_ID_Start, + POP_PROP, UNICODE_PROP_ID_Continue1, + POP_XOR, + POP_END); + break; +#endif + default: + if (prop_idx >= countof(unicode_prop_table)) + return -2; + ret = unicode_prop1(cr, prop_idx); + break; + } + return ret; +} + +#endif /* CONFIG_ALL_UNICODE */ diff --git a/libunicode.h b/libunicode.h new file mode 100644 index 0000000..0acc209 --- /dev/null +++ b/libunicode.h @@ -0,0 +1,124 @@ +/* + * Unicode utilities + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * 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. + */ +#ifndef LIBUNICODE_H +#define LIBUNICODE_H + +#include + +#define LRE_BOOL int /* for documentation purposes */ + +/* define it to include all the unicode tables (40KB larger) */ +#define CONFIG_ALL_UNICODE + +#define LRE_CC_RES_LEN_MAX 3 + +typedef enum { + UNICODE_NFC, + UNICODE_NFD, + UNICODE_NFKC, + UNICODE_NFKD, +} UnicodeNormalizationEnum; + +int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); +LRE_BOOL lre_is_cased(uint32_t c); +LRE_BOOL lre_is_case_ignorable(uint32_t c); + +/* char ranges */ + +typedef struct { + int len; /* in points, always even */ + int size; + uint32_t *points; /* points sorted by increasing value */ + void *mem_opaque; + void *(*realloc_func)(void *opaque, void *ptr, size_t size); +} CharRange; + +typedef enum { + CR_OP_UNION, + CR_OP_INTER, + CR_OP_XOR, +} CharRangeOpEnum; + +void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); +void cr_free(CharRange *cr); +int cr_realloc(CharRange *cr, int size); +int cr_copy(CharRange *cr, const CharRange *cr1); + +static inline int cr_add_point(CharRange *cr, uint32_t v) +{ + if (cr->len >= cr->size) { + if (cr_realloc(cr, cr->len + 1)) + return -1; + } + cr->points[cr->len++] = v; + return 0; +} + +static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2) +{ + if ((cr->len + 2) > cr->size) { + if (cr_realloc(cr, cr->len + 2)) + return -1; + } + cr->points[cr->len++] = c1; + cr->points[cr->len++] = c2; + return 0; +} + +int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len); + +static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2) +{ + uint32_t b_pt[2]; + b_pt[0] = c1; + b_pt[1] = c2 + 1; + return cr_union1(cr, b_pt, 2); +} + +int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, + const uint32_t *b_pt, int b_len, int op); + +int cr_invert(CharRange *cr); + +#ifdef CONFIG_ALL_UNICODE + +LRE_BOOL lre_is_id_start(uint32_t c); +LRE_BOOL lre_is_id_continue(uint32_t c); + +int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, + UnicodeNormalizationEnum n_type, + void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); + +/* Unicode character range functions */ + +int unicode_script(CharRange *cr, + const char *script_name, LRE_BOOL is_ext); +int unicode_general_category(CharRange *cr, const char *gc_name); +int unicode_prop(CharRange *cr, const char *prop_name); + +#endif /* CONFIG_ALL_UNICODE */ + +#undef LRE_BOOL + +#endif /* LIBUNICODE_H */ diff --git a/search.c b/search.c index 5cda5d5..1919b75 100644 --- a/search.c +++ b/search.c @@ -26,6 +26,18 @@ #include "qe.h" #include "variables.h" +#ifdef CONFIG_REGEX +#include "libregexp.h" + +BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size) { + return FALSE; +} + +void *lre_realloc(void *opaque, void *ptr, size_t size) { + return qe_realloc(&ptr, size); +} +#endif + /* Search stuff */ #define SEARCH_FLAG_DEFAULT SEARCH_FLAG_SMARTCASE @@ -164,6 +176,93 @@ static int eb_search(EditBuffer *b, int dir, int flags, } } +#ifdef CONFIG_REGEX + if (flags & SEARCH_FLAG_REGEX) { + char error_message[100]; + char source[SEARCH_LENGTH]; + int source_len; + uint8_t *regexp_bytes = NULL; + int regexp_len; + uint8_t **capture = NULL; + int capture_num; + int res = 0; + int re_flags = 0; + int found; + + re_flags |= LRE_FLAG_MULTILINE; + if (flags & SEARCH_FLAG_IGNORECASE) + re_flags |= LRE_FLAG_IGNORECASE; + if (dir < 0) + re_flags |= LRE_FLAG_STICKY; + + source_len = char32_to_utf8(source, countof(source), buf, len); + if (source_len >= countof(source)) + return -1; + regexp_bytes = lre_compile(®exp_len, error_message, sizeof(error_message), + source, source_len, re_flags, NULL); + if (regexp_bytes == NULL) { + //put_status(NULL, "regexp compile error: %s", error_message); + return -1; + } + capture_num = lre_get_capture_count(regexp_bytes); + capture = qe_malloc_array(uint8_t *, 2 * capture_num); + if (capture_num == 0 || capture == NULL) { + qe_free(®exp_bytes); + qe_free(&capture); + //put_status(NULL, "cannot allocate capture array for %d entries", capture_num); + return -1; + } + for (offset1 = offset;;) { + if (dir < 0) { + if (offset == 0) + break; + offset = eb_prev(b, offset); + } else { + offset = offset1; + if (offset >= end_offset) + break; + offset1 = eb_next(b, offset); + } + if ((offset & 0xffff) == 0) { + /* check for search abort every 64K */ + if (abort_func && abort_func(abort_opaque)) { + res = -1; + break; + } + } + /* Pass boundary characters to match $ and \b or \B */ + found = lre_exec(capture, regexp_bytes, + (const uint8_t *)b, offset, end_offset, 0, NULL, + eb_prevc(b, offset, &offset3), eb_nextc(b, end_offset, &offset3), + (unsigned int (*)(const uint8_t *bc_buf, int offset, int *offsetp))eb_nextc, + (unsigned int (*)(const uint8_t *bc_buf, int offset, int *offsetp))eb_prevc); + if (found < 0) { + res = -1; + break; + } + if (found > 0) { + int start = capture[0] - (uint8_t *)(void *)b; + int end = capture[1] - (uint8_t *)(void *)b; + if ((dir >= 0 || end <= end_offset) + && (!(flags & SEARCH_FLAG_WORD) || + (qe_isword(eb_prevc(b, start, &offset3)) && + qe_isword(eb_nextc(b, end, &offset3))))) + { + *found_offset = start; + *found_end = end; + res = 1; + break; + } + } + if (dir >= 0) + break; + } + qe_free(®exp_bytes); + qe_free(&capture); + return res; + } +#endif + for (offset1 = offset;;) { if (dir < 0) { if (offset == 0) @@ -385,6 +484,12 @@ static void isearch_run(ISearchState *is) { s->region_style = 0; is->found_offset = -1; } else { + if (search_offset == is->found_offset + && search_offset == is->found_end) { + /* zero width match: skip one character */ + if (is->dir > 0) + search_offset = eb_next(s->b, search_offset); + } if (eb_search(s->b, is->dir, flags, search_offset, s->b->total_size, is->search_u32, is->search_u32_len, @@ -856,6 +961,14 @@ void isearch_colorize_matches(EditState *s, char32_t *buf, int len, if (found_offset >= offset_end) break; + if (found_end <= found_offset) { + /* zero width match: skip one character. + * for example `a*` finds matches everywhere but should highlight + * all sequences of letters a + */ + offset = eb_next(b, found_end); + continue; + } if (found_end > offset_start) { /* Compute character positions */ start = 0; @@ -892,7 +1005,7 @@ typedef struct QueryReplaceState { char32_t search_u32[SEARCH_LENGTH]; /* code points */ /* query-replace */ char replace_str[SEARCH_LENGTH * 3]; /* may be in hex */ - char32_t replace_u32[SEARCH_LENGTH]; /* code points (useless?) */ + char32_t replace_u32[SEARCH_LENGTH]; /* code points */ } QueryReplaceState; static void query_replace_help(QueryReplaceState *is) {